gpt4 book ai didi

ios - WKWebview getAllCookies 在 iOS 11.3 中崩溃

转载 作者:可可西里 更新时间:2023-11-01 03:09:46 24 4
gpt4 key购买 nike

我们最近迁移到了 WKWebview。我们为 cookie 更改添加了一个监听器,以获取更新的 cookie 并更新我们自己的商店。

- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore {
[cookieStore getAllCookies:^(NSArray* cookies) {
}];
}

加载 Controller 后,它会调用 cookiesDidChangeInCookieStore 并在“getAllCookies”处崩溃。但此崩溃仅发生在 TestFlight/Fabric 构建中。当我直接从 xcode 在设备上运行应用程序时不会发生(在调试和 Release模式下)。以下是崩溃报告,

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

调用 getAllCookies 时看起来有溢出。这仅在 iOS 11.3 中发生。

最佳答案

经过一些调查,我们得出以下有效解决方案:

背景故事

当用户更新到我们应用程序的更新版本时,我们会发生崩溃。

问题

我们正在使用 UIWebView 并将 cookie 注入(inject)其中。问题出现在:

  • 用户安装使用 WKWebview 的新更新应用。
  • 用户打开 WebView 。
  • 我们尝试通过调用组件 wkhttpcookieestore 上的 getAllCookies(_ completionHandler: @escaping ([HTTPCookie]) -> Void) 来检索所有之前 UIWebView 注入(inject)的 cookie,所以我们可以遍历它们并一一删除它们。

判决

UIWebView 使用nshttpcookiestorage: https://developer.apple.com/documentation/foundation/nshttpcookiestorage

WKWebView 使用 wkhttpcookieestore: https://developer.apple.com/documentation/webkit/wkhttpcookiestore

当我们尝试检索 cookie 时,在从 nshttpcookiestoragewkhttpcookieestore 的同步过程中的某处,它正在将其中一个值作为 NSURL 传递,然后有人正在该对象上调用 length() 函数,但由于 NSURL 没有该函数而崩溃。

决议

因此,我们应该使用正确的方法删除设置在 nshttpcookiestorage 上的 cookie:HTTPCookieStorage.shared.removeCookies(since: Date.distantPast) 然后使用正确的方法从 wkhttpcookieestore 中删除 cookies,即 removeData(ofTypes:for:completionHandler :) 并将类型设置为 WKWebsiteDataTypeCookies 而不是遍历所有 cookie 并一一删除它们。

测试注意事项

所有测试必须在真实设备 (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()
}
}
}

关于ios - WKWebview getAllCookies 在 iOS 11.3 中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49954273/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com