11
votes

I need to share cookies between WKWebView instances - for this i'm using a single WKWebViewConfiguration instance which is then used to init every WKWebView.

In order to do this I assume I have to use a shared WKProcessPool, ex:

let websiteDataStore = WKWebsiteDataStore.default()
websiteDataStore.httpCookieStore.add(self)

let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = websiteDataStore
configuration.processPool = WKProcessPool()   /* !!! */

However doing so causes the setCookie completion handler to NOT fire.

let cookieStore = self.webConfiguration.websiteDataStore.httpCookieStore
     cookieStore.setCookie(cookie, completionHandler: {
})

If i do not set the WKProcessPool (*) instance - then completion block fires fine, but obviously WebViews do not see the cookies ; / Did anyone encounter this? Ideas on how else to share the cookies?

iOS: 11.2.6

2
Another interesting observation is that this problem does not occur on simulator.Pawel Klapuch
This problem does not occur on iOS 12, but another cookie problem occurs on iOS 12. I hate WKWebView.fthdgn
This callback is not triggered if the method is inside of DispatchQueue.main.async / sync.fthdgn

2 Answers

5
votes

After further testing I've managed to find solution - although i'm not sure what is happening. In short - above completion handler fires OK after WKWebView is instantiated.

In my case I need to set some cookies after login (so no webviews are displayed ATM). So calling setCookie only queues these operations somewhere - they are flushed when web client is fired. If someone can link documentation - that's be great!


UPDATE

So as this issue is still present - I've finally got back to this. My solution for now is to:

  1. Cache cookie value in keychain (every time app calls HTTPCookieStore.setCookie - which may complete or not (which is the problem)

  2. When HTTPCookieStore.setCookie{ } completion block fires (confirmation that cookie was indeed set) i then remove the value from keychain and webview is now responsible for lifecycle of the cookie value)

  3. On every start of app i check if cookie values are cached in keychain -> if so HTTPCookieStore.setCookie()

Above can loop infinitely UNTIL webview is actually opened.

1
votes

My problem was with deleting cookies to log a user out of the application. The completion handler for getAllCookies() was not firing, so what is working for me is forcing the webView to reload which will flush the queue and delete the cookies.

webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
    for cookie in cookies {
        if cookie.name == "authentication" {
            self.webView.configuration.websiteDataStore.httpCookieStore.delete(cookie)
        }
    }
}
webView.reload()