iOS 11.2.6下设置WKProcessPool致setCookie回调不触发问题求助
我之前在iOS 11.x版本开发时碰到过一模一样的问题,给你几个亲测有效的思路和解决方案:
1. 先排查WKProcessPool的使用方式
你当前的代码里configuration.processPool = WKProcessPool()虽然是给同一个Configuration赋值,但要注意:必须确保整个APP里只有一个全局共享的WKProcessPool实例,最好把它定义成单例,否则iOS 11很容易出现Cookie共享异常或者回调不触发的问题:
// 定义全局共享的ProcessPool单例 let sharedProcessPool = WKProcessPool() // 初始化Configuration时使用这个单例 let websiteDataStore = WKWebsiteDataStore.default() websiteDataStore.httpCookieStore.add(self) let configuration = WKWebViewConfiguration() configuration.websiteDataStore = websiteDataStore configuration.processPool = sharedProcessPool // 用全局单例,不要每次新建
2. 解决setCookie回调不触发的iOS 11特定bug
这是iOS 11.x版本WKWebView的已知bug:当WKProcessPool和WKWebsiteDataStore绑定后,如果还没有WebView实际使用这个Configuration,调用setCookie的completion handler可能不会触发。
解决办法:
- 先初始化一个WKWebView实例(哪怕是加载空白页面
about:blank),等WebView完成初始化后,再调用setCookie; - 或者给
setCookie加一个短暂延迟,确保ProcessPool和DataStore完成绑定。
示例代码:
// 先初始化WebView并加载空白页 let webView = WKWebView(frame: .zero, configuration: webConfiguration) webView.load(URLRequest(url: URL(string: "about:blank")!)) // 延迟设置Cookie DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { let cookieStore = self.webConfiguration.websiteDataStore.httpCookieStore cookieStore.setCookie(cookie) { // 现在回调应该能正常触发了 print("Cookie设置完成") } }
3. 备选方案:手动拦截请求添加Cookie
如果上面的方法还是有问题,可以绕过WKProcessPool的共享机制,手动在每个WebView的请求里添加Cookie,这个方案在iOS 11上稳定性反而更好:
步骤1:同步WKHTTPCookieStore和HTTPCookieStorage
在WKHTTPCookieStoreObserver的回调里,把Cookie同步到系统的HTTPCookieStorage.shared:
func cookiesDidChange(in cookieStore: WKHTTPCookieStore) { cookieStore.getAllCookies { cookies in let storage = HTTPCookieStorage.shared storage.removeCookies(since: Date.distantPast) cookies.forEach { storage.setCookie($0) } } }
步骤2:拦截WebView请求并添加Cookie
给每个WebView设置navigationDelegate,在请求发送前手动添加Cookie到请求头:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } var mutableRequest = navigationAction.request if let cookies = HTTPCookieStorage.shared.cookies(for: url) { let cookieHeader = HTTPCookie.requestHeaderFields(with: cookies) mutableRequest.allHTTPHeaderFields?.merge(cookieHeader) { _, new in new } } decisionHandler(.allow) }
总结
优先确保使用全局单例的WKProcessPool,再结合延迟设置Cookie的方式解决回调不触发的问题;如果还是不行,就用手动拦截请求添加Cookie的方案,这个在iOS 11上是比较可靠的替代方案。
内容的提问来源于stack exchange,提问作者Pawel Klapuch
相关产品推荐
相关产品推荐

