关闭并打开网络视图后,WKHTTPCookieStorage的setCookie无法返回

时间:2018-03-29 18:15:37

标签: ios swift webkit nshttpcookie wkhttpcookiestore

我有以下代码将Cookie从一般HTTPCookieStorage复制到我的webview的cookie商店中。复制完所有cookie后,我加载webview

    let webView = WKWebView(frame: containerView.bounds, configuration: WKWebViewConfiguration())
    webView.navigationDelegate = navigationDelegate
    containerView.addAndFillSubview(webView)
    guard let sharedCookies = HTTPCookieStorage.shared.cookies else {
        return
    }

    // For each cookie in the common store, set it in the WKWebView's store.
    for sharedCookie in sharedCookies {
        // Add a block to the dispatch group every time a cookie begins to be set in the WKWebView's store.
        wkSetCookieDispatchGroup.enter() 
        webView.configuration.websiteDataStore.httpCookieStore.setCookie(sharedCookie) {
           // Release a block from the dispatch group every time a cookie is successfully set in the WKWebView's store.
           wkSetCookieDispatchGroup.leave()
        }
    }

    // Wait for all the cookies to be successfully set (all blocks in the wkSetCookieDispatchGroup to be released)
    wkSetCookieDispatchGroup.notify(queue: .main) {
       // Load url in webView
    }

此代码第一次运行时 - 所有Cookie都已设置,setCookie的完成处理程序被调用,并且通知了调度组。

但是,在关闭此Web视图并打开它的n次运行(通常是3或4次)之后,setCookie的完成处理程序STOP通常无限期地返回。有一些竞争条件正在发生,因为如果我设置断点并在每次打开Web视图时点击它们,则此问题永远不会发生。在它发生一次之后,设置断点有时会让它重新开始工作,有时候什么都不做。

注意:这仅在设备上发生。在模拟器上,这永远不会发生。

没有关于setCookie完成时候手应该返回或不返回的文档,以及这是一种竞争条件,这种情况通常在您休息时不会发生点使得调试非常困难。

还有其他人经历过这个吗?有什么建议?我曾尝试在几个地方明确设置WKProcessPool,但这并不起作用。我尝试在创建配置之前和之后创建Web视图。我已经尝试了很多东西,但仍然丢失了

2 个答案:

答案 0 :(得分:0)

不确定这是否符合您的要求,但我遇到了同样的问题,发现我正在创建的每个WKWebViewConfiguration都使用相同的Cookie存储,以便与其他WKWebView一起使用。

我最终要做的是因为我需要为我将使用的任何wk webview实例使用相同的cookie创建一个单独的WKWebViewConfiguration,它会添加一次所需的cookie,设置WKProcessPool然后返回一个副本。

我需要的每个不同的wk webview都会在副本上设置自定义配置,但不必与cookie商店进行交互。

在遇到同样的问题后似乎对我有用。

答案 1 :(得分:0)

尝试通过将键Apple Transport Security添加到Allow Arbitrary Loads来关闭info.plist中的YES。 (只是为了解决问题,即使解决了问题,也不要鼓励这样做)

根据我的经验,如果您的应用向Apple Transport Security(ATS)确认,并且您尝试调用设置不安全 cookie,则不会调用setCookie完成处理程序块。

PS:从iOS 12.2开始,这似乎是WebKit的未记录事实

以下是我在我们的iOS应用中个人注意到的详细信息-

我们在符合ATS的应用中具有以下代码,可在加载经过身份验证的请求网址之前复制Cookie-

        let cookieGroup = DispatchGroup()
        for cookie in cookieList {
            cookieGroup.enter()
            dataStore.httpCookieStore.setCookie(cookie) { cookieGroup.leave() }
        }
        cookieGroup.notify(queue: DispatchQueue.main) {
            config.websiteDataStore = dataStore
            completion(config)
        }

以下cookie(注意isSecure: FALSE)无法设置,因此无法执行平衡leave(),因此从不执行notify块。

<NSHTTPCookie
    version:1
    name:TESTNAME
    value:BD61035906F6FFFF79D6CEF1F8FFD74ACD03CFC76A758FBBB78C8BC3D6C2C4C3F7B239BBE8C7C3A6FBEF1D903B5AE4FFFF50B9749C2C3593DC2D36FA0CBD695296EC958A
    expiresDate:'2019-05-08 16:10:43 +0000'
    created:'2019-05-07 16:10:43 +0000'
    sessionOnly:FALSE
    domain:SOME_DOMAIN_TEST
    partition:none
    sameSite:none
    path:/
    isSecure:FALSE
 path:"/" isSecure:FALSE>

(上面更改了名称和域名以掩盖来源)