2

I am making an app which makes decision of user login / logged out and other activities based on WkWebView cookies. Most of the time , it works fine. Sometimes , it failed to fetch cookies when login URL succeeded. And fails to delete the cookies when user logged out. Even , when i quickly login or logged out, it shows the wrong/previous token of the session.

My implementation is like :

    func loadWebView () {

    let webConfiguration = WKWebViewConfiguration()
    webView = WKWebView(frame:  UIScreen.main.bounds, configuration: webConfiguration )
    webView.customUserAgent = APP_IDENTITY.appending("|") + Utility.deviceID().appending("|") + PSUserDefaults.getFCMToken()

    webView.navigationDelegate = self
    webView.uiDelegate = self
    webView.load(DOMAIN_URL)
  }

extension WKWebView {
func load(_ urlString: String) {
    if let url = URL(string: urlString) {
        let request = URLRequest(url: url)
        load(request)
    }
}

func cleanAllCookies() {
    HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
    print("All cookies deleted")

    WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
        records.forEach { record in
                WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
                print("Cookie ::: \(record) deleted")
        }
    }
}

func refreshCookies() {
    self.configuration.processPool = WKProcessPool()
}

func removeCookies(){
    let cookie = HTTPCookie.self
    let cookieJar = HTTPCookieStorage.shared

    for cookie in cookieJar.cookies! {
        cookieJar.deleteCookie(cookie)
        print("removeCookies")
    }
 }
  }

And the delegate is :

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
 // i am getting the cookies here most of the time. Sometimes , it failed to sync the cookies from here. 
     if #available(iOS 11.0, *) {
        print(webView.configuration.websiteDataStore.httpCookieStore.getAllCookies({ (webViewCookies) in

            let wkHttpCookieStorage = WKWebsiteDataStore.default().httpCookieStore;

            wkHttpCookieStorage.getAllCookies { (cookies) in
                // Nothing comes here sometimes !
                for cookie in cookies { 
                  }
 }

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    print("decidePolicyFor navigationAction : \(navigationAction.request.url!)")
   // Each URl navigation is happen properly on time 
   }

// I was checking the HTTPCookieStorage with a timer when it fails to get cookies in didFinish (wkwbeview ...) delegate method.  
func checkHTTPCookieStorage (){

        let cookieJar = HTTPCookieStorage.shared
        for cookie in cookieJar.cookies! {
              }
  }

I also check the print(webView.configuration.websiteDataStore.httpCookieStore.getAllCookies({ (webViewCookies) in {} values with a timer when it fails to fetch cookies. Nothing works sometimes. 

In logged out , i am deleting the cookies manually from extension method in all ways:

         self.webView.cleanAllCookies()
         self.webView.removeCookies()

Observation : Most of the case it gets cookies in login and can delete cookies in logged out. Sometimes it takes 3~10 second and get cookies when i apply a timer to fetch cookies. Sometimes it totally failed. I need to re launch the app then it gets cookies. This is embarrassing!

I have seen some blog, report , post on wkWebview cookies issues but nothing helped me.

My question :

  1. How i can get/delete cookies all the time properly ?
  2. Any wrong with my implementation ?

Thanks all.

Jamshed Alam
  • 10,887
  • 5
  • 22
  • 42
  • Since you're experiencing the problems only sporadically, it may be a threading issue. I'd suggest you test your app with the Main Thread Checker activated (Edit Scheme dialog / Diagnostics tab in Xcode). WebKit is a main-thread-only framework so all access to methods/functions must come from the main thread - if there should be an issue in your app, the main thread checker will detect it and give you a warning. – Lutz Mar 01 '19 at 07:36
  • @Lutz , already checked that. No benefit. – Jamshed Alam Mar 02 '19 at 03:37
  • @JamshedAlam did you find a solution for it? – sliwinski.lukas Oct 17 '19 at 12:19
  • @sliwinski.lukas, Answer posted. Tell me if you need more info. – Jamshed Alam Oct 17 '19 at 17:58

1 Answers1

1

I found some strange behaviour in different iOS version. Some iOS version saves cookies in

WKWebsiteDataStore.default().httpCookieStore 

and some iOS version saves it in

HTTPCookieStorage.shared.cookies!

And it takes 3~10 seconds to receive/set cookies from web URL. I run a thread to check the cookies in both store. It works!

Jamshed Alam
  • 10,887
  • 5
  • 22
  • 42