Reputation: 308
i need to use same configuration (cookie) on the second WebView after the user is authorized on first WebView. On simulator it's work well, but on device is not stable.
class auth: UIViewController, WKNavigationDelegate, UIWebViewDelegate {
private var webView: WKWebView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
loadPage(urlString: link)
}
private func loadPage(urlString: String) {
if let encodedURL = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: encodedURL) {
let request = URLRequest(url: url)
webView.refreshCookies()
webView.load(request)
}
}
}
extension WKWebView {
func refreshCookies() {
self.configuration.websiteDataStore = WKWebsiteDataStore.default()
}
}
Upvotes: 0
Views: 2283
Reputation: 276
Instead of keeping a global cookie variable or saving to plist as mentioned above, you can set cookies in the shared HTTPCookieStorage.
To store:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let request = navigationAction.request
let url = request.url
webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { (cookies) in
HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
}
decisionHandler(.allow)
return
}
And to retrieve and set (in a different WebView instance):
let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
let config = WKWebViewConfiguration()
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}
let webView2 = WKWebView(frame: frame, configuration: config)
Hope this is helpful
Upvotes: 1
Reputation: 2778
Every ** WKWebView** has it's own cookie space that cookie space is saved in WKProcessPool just make process pool object global and assign to every webview object, hope so this will work in your case.
static let processPool = WKProcessPool()
And set your WKWebView instance every time with this process pool, other way is whenever you creating wkwebview and load implement this function.
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
// use to sync cookies
guard let response = navigationResponse.response as? HTTPURLResponse, let responseUrl = navigationResponse.response.url else {
decisionHandler(.cancel)
return
}
if #available(iOS 11.0, *) {
self.webView.httpCookieStore.getAllCookies { (cookies) in
cookies.forEach({ (cookie) in
if cookie.name == Constant.appCodeCookie || cookie.name == Constant.rpgaCookieName || cookie.name == Constant.headerCookie , cookie.name == Constant.adIdCookie {
HTTPCookieStorage.shared.setCookie(cookie)
}
})
}
} else {
// Fallback version
if let allHttpHeaders = response.allHeaderFields as? [String: String] {
let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHttpHeaders, for: responseUrl)
for cookie in cookies {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
}
decisionHandler(.allow)
}
Every time you make instance of wkwebview just get all cookies from httpcookiestorage and set in wkwebview user script for further you can check my answer here also. Can I set the cookies to be used by a WKWebView?
Upvotes: 1
Reputation: 1
You need to set cookie for each wkwebview, So keep the cookie value as global variable or save it in plist.
Upvotes: 0