将WKWebView的Cookie同步到NSHTTPCookieStorage

3

WKWebView可以通过WKHTTPCookieStorage管理自己的cookie,与NSHTTPCookieStorage独立。我该如何将WKHTTPCookieStore中的cookie同步到NSHTTPCookieStorage

我的目标是使WKHTTPCookieStoreNSHTTPCookieStorage之间的cookie同步。

我尝试使用实现观察者方法WKHTTPCookieStoreObserver来同步cookie。

- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore {
[cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> *array) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSArray *nsHttpCookies = cookieStorage.cookies;

    //add new Cookie from wkWebView
    [array enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
        if(![nsHttpCookies containsObject:cookie]){
            [cookieStorage setCookie:cookie];
        }
    }];

    //add old Cookie from wkWebView
    [nsHttpCookies enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
        if(![array containsObject:cookie]){
            [cookieStorage deleteCookie:cookie];
        }
    }];
}];
}

这是同步 WKWebView 中 cookie 到 NSHTTPCookieStorage 的正确方式吗?

嘿,你试过使用WKNavigationDelegate吗?也许你可以使用WKNavigationResponse并从urlResponse中提取头字段。在头字段中,你应该有一个Cookie头作为字符串。然后你可以将其分解并比较缺少什么。这只是一个想法。 - Ben
不幸的是,在iOS 13中,观察者方法根本没有被调用...(https://stackoverflow.com/q/58397343/2778898)。因此,我决定在启动新请求时手动实现同步。 - LaborEtArs
1个回答

3

正如Ben在评论中回答的那样,您需要从响应头中提取cookie,并手动将其设置在HTTPCookieStorage中。

Swift 4:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) {
    guard
        let response = navigationResponse.response as? HTTPURLResponse,
        let url = navigationResponse.response.url
    else {
        decisionHandler(.cancel)
        return
    }

    if let headerFields = response.allHeaderFields as? [String: String] {
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
        cookies.forEach { (cookie) in
             HTTPCookieStorage.shared.setCookie(cookie)
        }
    }

    decisionHandler(.allow)
}

Objective-C:

NSHTTPURLResponse * resp = (NSHTTPURLResponse*)[navigationResponse response];
NSDictionary  *diction = [resp allHeaderFields];

NSArray * cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:diction forURL:[resp URL]];

for (NSHTTPCookie *cookie in cookies) {
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}

return decisionHandler(YES);

似乎头部不再包含cookie。你有其他建议吗? - Hari Ram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接