代码之家  ›  专栏  ›  技术社区  ›  Lorenzo B

在iOS 12中设置WKWebView cookie接受策略

  •  1
  • Lorenzo B  · 技术社区  · 7 年前

    目标:将第三方cookie注入 WKWebView .

    在iOS 12之前,我通过这段代码解决了这个问题(参见 https://medium.com/@flexaddicted/how-to-set-wkwebview-cookie-accept-policy-d8a2d3b77420 ):

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
      guard let response = navigationResponse.response as? HTTPURLResponse,
        let url = navigationResponse.response.url else {
        decisionHandler(.cancel)
        return
      }
    
      if let headerFields = response.allHeaderFields as? [String: String] {
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
        cookies.forEach { cookie in
          webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
        }
      }
    
      decisionHandler(.allow)
    }
    

    从iOS 12开始,Cookie在中不可用 WKWebView 奥巴马的回应。

    https://bugs.webkit.org/show_bug.cgi?id=188691

    你知道解决这个问题的方法吗?

    0 回复  |  直到 7 年前
        1
  •  0
  •   Florent Morin    6 年前

    我想我找到了解决办法,但有点“黑客”。

    创建一个返回URL的方法:

    1. 创建一个 DispatchSemaphore 发送同步请求
    2. 在中执行请求 URLSession
    3. 在DataTask结束时,检索响应?。网址

    在加载内容之前 WKWebView ,放入饼干 WKWebView 从…起 URLSession .

    它就像一个符咒。

    func getAuthenticatedURL(from url: URL) -> URL? {
        let session = URLSession.shared
        let semaphore = DispatchSemaphore(value:0)
    
        var result: URL? = nil
    
        session.dataTask(with: url) { _, response, _ in
            result = response?.url
            semaphore.signal()
        }.resume()
    
        semaphore.wait()
    
        return result
    }
    
    
    let conf = WKWebViewConfiguration()
    
    let ctrl = WKUserContentController()
    
    conf.userContentController = ctrl
    
    let wkDataStore = WKWebsiteDataStore.nonPersistent()
    
    wkDataStore.removeData(
        ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),     
        modifiedSince: .distantPast) { }
    
    HTTPCookieStorage.shared
                    .cookies?
                    .forEach { wkDataStore.httpCookieStore.setCookie($0) }
    
    conf.websiteDataStore = wkDataStore
    
    wkWebView = WKWebView(frame: .zero, configuration: conf)
    
    // ...
    
    // Get URL from getAuthenticatedURL and load in wkWebView