如何在不同的WKWebViews上使用相同的cookie

时间:2018-05-16 18:27:10

标签: swift wkwebview wkwebviewconfiguration

我需要在第一个WebView上授权用户后在第二个WebView上使用相同的配置(cookie)。在模拟器上它运行良好,但在设备上不稳定。

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()
    }
}

3 个答案:

答案 0 :(得分:1)

您不必像上面提到的那样保留全局cookie变量或保存到plist,而是可以在共享的HTTPCookieStorage中设置cookie。

要存储:

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
}

要检索和设置(在另一个WebView实例中):

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)

希望这很有帮助

答案 1 :(得分:0)

您需要为每个wkwebview设置cookie,因此请将cookie值保留为全局变量或将其保存在plist中。

答案 2 :(得分:0)

每个** WKWebView **都有它自己的cookie空间,即cookie空间保存在 WKProcessPool 中,只是使进程池对象成为全局对象并分配给每个webview对象,希望这样可以在您的情况下起作用。

    static let processPool = WKProcessPool()

每次使用此进程池设置WKWebView实例,其他方法是每次创建wkwebview并加载实现此功能时。

 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)
}

每次创建wkwebview实例时,只需从httpcookiestorage获取所有cookie并在wkwebview用户脚本中进行设置,就可以进一步在这里查看我的答案。 Can I set the cookies to be used by a WKWebView?