【问题标题】:WKWebview getAllCookies crash in iOS 11.3WKWebview getAllCookies 在 iOS 11.3 中崩溃
【发布时间】:2018-10-01 22:00:00
【问题描述】:

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

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

加载控制器后,它会调用 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

调用 getAllCookies 时似乎存在溢出。这只发生在 iOS 11.3 中。

【问题讨论】:

  • 看来您可能需要向 Apple 提交错误报告,看看他们怎么说:bugreport.apple.com
  • 您能否解决此崩溃问题?我也面临同样的问题。
  • 请查看底部的解决方案stackoverflow.com/questions/49954273/… 并接受它是否适合您。选择的答案不正确,因为线程不是解决方案:) 谢谢!

标签: ios wkwebview wkwebviewconfiguration wkhttpcookiestore ios11.3


【解决方案1】:

经过一番调查,我们得出了以下可行的解决方案:

背景故事

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

问题

我们使用 UIWebView 并将 cookie 注入其中。问题来了:

  • 用户安装使用 WKWebview 的新更新应用程序。
  • 用户打开一个网络视图。
  • 我们尝试通过在组件wkhttpcookiestore 上调用getAllCookies(_ completionHandler: @escaping ([HTTPCookie]) -&gt; Void) 来检索所有先前UIWebView 注入的cookie,这样我们就可以遍历它们并一一删除它们。

判决

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

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

在从nshttpcookiestoragewkhttpcookiestore 的同步过程中,当我们尝试检索cookie 时,它​​会将其中一个值作为NSURL 传递,然后有人在该对象上调用length() 函数崩溃是因为 NSURL 没有那个功能。

分辨率

因此,我们应该使用正确的方法删除在nshttpcookiestorage 上设置的cookie,方法是使用: HTTPCookieStorage.shared.removeCookies(since: Date.distantPast),然后使用正确的方法 removeData(ofTypes:for:completionHandler:)wkhttpcookiestore 中删除 cookie,并将类型设置为 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()
        }
    }
}

【讨论】:

    【解决方案2】:

    我能够通过在主线程中异步调用 getAllCookies 来修复这个崩溃。

    func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
         DispatchQueue.main.async {
             cookieStore.getAllCookies { (cookies) in
                 //Code here...
             })
         }
    }
    

    【讨论】:

    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多