spp*_*spp 8 ios wkwebview wkwebviewconfiguration wkhttpcookiestore ios11.3
我们最近迁移到了WKWebview.我们添加了一个用于更改cookie的监听器,以获取更新的cookie并更新我们自己的商店.
- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore {
[cookieStore getAllCookies:^(NSArray* cookies) {
}];
}
Run Code Online (Sandbox Code Playgroud)
加载控制器后,它会调用cookiesDidChangeInCookieStore并在"getAllCookies"崩溃.但这种崩溃只发生在TestFlight/Fabric构建中.当我从xcode直接在设备上运行应用程序时(在调试和发布模式下)都不会发生.以下是崩溃报告,
Thread 9 name: WebThread
Thread 9 Crashed:
0 WebKit 0x0000000192fbfc10 WebKit::CallbackMap::put+ 1186832 (WTF::Ref<WebKit::CallbackBase, WTF::DumbPtrTraits<WebKit::CallbackBase> >&&) + 128
1 WebKit 0x0000000192fbfbb4 WebKit::CallbackMap::put+ 1186740 (WTF::Ref<WebKit::CallbackBase, WTF::DumbPtrTraits<WebKit::CallbackBase> >&&) + 36
2 WebKit 0x00000001930490cc WebKit::CallbackID WebKit::CallbackMap::put<WTF::Vector<WebCore::Cookie, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WebKit::CallbackBase::Error>(WTF::Function<void + 1749196 (WTF::Vector<WebCore::Cookie, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WebKit::CallbackBase::Error)>&&) + 136
3 WebKit 0x0000000193049008 WebKit::WebCookieManagerProxy::getAllCookies(PAL::SessionID, WTF::Function<void + 1749000 (WTF::Vector<WebCore::Cookie, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&, WebKit::CallbackBase::Error)>&&) + 44
4 WebKit 0x0000000192eb5b90 API::HTTPCookieStore::cookies(WTF::Function<void + 97168 (WTF::Vector<WebCore::Cookie, 0ul, WTF::CrashOnOverflow, 16ul, WTF::FastMalloc> const&)>&&) + 124
5 WebKit 0x00000001931fbdf8 -[WKHTTPCookieStore getAllCookies:] + 92
6 WebKit 0x00000001931fc96c WKHTTPCookieStoreObserver::cookiesDidChange+ 3533164 (API::HTTPCookieStore&) + 44
7 WebKit 0x0000000192eb61b0 API::HTTPCookieStore::cookiesDidChange+ 98736 () + 72
8 JavaScriptCore 0x000000018a0e17d4 WTF::dispatchFunctionsFromMainThread+ 6100 () + 344
9 JavaScriptCore 0x000000018a208650 WTF::timerFired+ 1214032 (__CFRunLoopTimer*, void*) + 40
10 CoreFoundation 0x0000000183527aa8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28
11 CoreFoundation 0x000000018352776c __CFRunLoopDoTimer + 864
12 CoreFoundation 0x0000000183527010 __CFRunLoopDoTimers + 248
13 CoreFoundation 0x0000000183524b60 __CFRunLoopRun + 2168
14 CoreFoundation 0x0000000183444da8 CFRunLoopRunSpecific + 552
15 WebCore 0x000000018b6d1dcc RunWebThread+ 265676 (void*) + 592
16 libsystem_pthread.dylib 0x00000001831a5220 _pthread_body + 272
17 libsystem_pthread.dylib 0x00000001831a5110 _pthread_body + 0
18 libsystem_pthread.dylib 0x00000001831a3b10 thread_start + 4
Run Code Online (Sandbox Code Playgroud)
调用getAllCookies时看起来有溢出.这只发生在iOS 11.3中.
经过调查,我们得出了以下可行的解决方案:
当用户更新到我们的应用程序的较新版本时,我们会崩溃。
我们正在使用UIWebView并将cookie注入其中。问题出现在以下情况:
getAllCookies(_ completionHandler: @escaping ([HTTPCookie]) -> Void)组件来检索以前所有UIWebView注入的cookie,wkhttpcookiestore以便我们可以遍历它们并将它们逐个删除。UIWebView使用nshttpcookiestorage:https :
//developer.apple.com/documentation/foundation/nshttpcookiestorage
WKWebView使用wkhttpcookiestore:https :
//developer.apple.com/documentation/webkit/wkhttpcookiestore
在从同步nshttpcookiestorage到wkhttpcookiestore尝试检索Cookie 的同步过程中的某个地方,它将其中一个值作为NSURL传递,然后有人length()在该对象上调用函数,由于NSURL没有该函数,该对象崩溃了。
因此,我们应该删除那些在设置的Cookie nshttpcookiestorage通过使用这是正确的方法:
HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)然后从删除的cookie wkhttpcookiestore与这是正确的方法removeData(ofTypes:for:completionHandler:),并设置类型WKWebsiteDataTypeCookies,而不是通过所有的饼干循环和消除他们一个一个。
所有测试必须在真实设备(iPhone / iPad)上进行,因为在iOS模拟器上无法重现此崩溃。
public func clearCookies(completion: @escaping (() -> Swift.Void)) {
// First remove any previous cookies set in the NSHTTP cookie storage.
HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
// Second remove any previous cookies set in the WKHTTP cookie storage.
let typeCookiesToBeRemoved: Set<String> = [WKWebsiteDataTypeCookies]
// Only fetch the records in the storage with a cookie type.
WKWebsiteDataStore.default().fetchDataRecords(ofTypes: typeCookiesToBeRemoved) { records in
let dispatchGroup = DispatchGroup()
records.forEach { record in
dispatchGroup.enter()
WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {
dispatchGroup.leave()
})
}
dispatchGroup.notify(queue: DispatchQueue.main) {
print("All cookies removed.")
completion()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我能够通过在主线程中异步调用 getAllCookies 来修复此崩溃。
func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
DispatchQueue.main.async {
cookieStore.getAllCookies { (cookies) in
//Code here...
})
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1242 次 |
| 最近记录: |