Reputation: 31
I am looking for solution for iOS 13
SDK WKWebview
based app built with SwiftUI
in order to make cookies saved between different sessions of app usage.
This problem has been numerously discussed acrossed stackoverflow provided with different soltuions for ObjectiveC
and Swift
with Storyboards
.
I am asking the community if there is ready to use code examlpe of how to provide WKWebView
Cookie Persistency on iOS 13
WKWebView
app with SwiftUI
used
To make it clear: my app accesses remote web server with web site designed to be like mobile app. It's not local web app with need to manipulate cookies locally. Simply to make cookies manipulation in web site from remote server in Jquery JS
code of the page in order to work and be saved across different sessions of app,
My current version of code:
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
WebView().edgesIgnoringSafeArea(.all)
}
}
struct WebView: UIViewRepresentable {
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.scrollView.isScrollEnabled = false
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
let liveView = "https://example.com/projectname/index.html"
if let url = URL(string: liveView) {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
Upvotes: 3
Views: 5648
Reputation: 67
You can use below approach to fetch all the cookies and inject desired ones back. Ideally get cookies from a secured page after logging in and save it in UserDefaults. Then inject the same when the app starts again:
struct WebView: UIViewRepresentable {
let url: URL
let cookies: [HTTPCookie]
@ObservedObject var webViewManager: WebViewManager
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.load(URLRequest(url: url))
webViewManager.webView = webView // Set the webView reference in the manager
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
// Update the view if needed
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
// Called when the web view begins to receive data from the server
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
print(webView.url as Any)
// If the URL is the login URL where the session token is obtained
if let url = webView.url, url.absoluteString == "https://my-url.com/path/" {
// Get session token from cookies after page redirects to desired url, say landing page
webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
for cookie in cookies {
if cookie.name == "session_token" {
// Save session token to UserDefaults
print(cookie.value)
UserDefaults.standard.set(cookie.value, forKey: "SessionToken")
}
}
}
}
}
}
func setCookies() {
webViewManager.setCookies(cookies)
}
}
class WebViewManager: ObservableObject {
var webView: WKWebView?
func setCookies(_ cookies: [HTTPCookie]) {
guard let webView = webView else { return }
let cookieStore =webView.configuration.websiteDataStore.httpCookieStore
cookies.forEach { cookieStore.setCookie($0) }
// Reload the web view after setting cookies
webView.reload()
}
}
struct ContentView: View {
@StateObject private var webViewHelper = WebViewHelper()
@ObservedObject var webViewManager = WebViewManager() // observe the manager
var body: some View {
WebView(url: webViewHelper.url, cookies: webViewHelper.cookies, webViewManager: webViewManager) // pass the observed manager
.onAppear {
webViewManager.setCookies(webViewHelper.cookies)
}
}
}
class WebViewHelper: ObservableObject {
let url = URL(string: "https://my-url.com/path/")!
let cookies: [HTTPCookie] = [
HTTPCookie(properties: [
.domain: "my-url.com",
.path: "/",
.name: "session_token",
.value: UserDefaults.standard.string(forKey: "SessionToken") as Any
])!
]
}
Upvotes: 0
Reputation: 2216
Set the configuration webView.configuration.websiteDataStore.httpCookieStore
see this answer for an example
Upvotes: 1