apo*_*rat 58 webkit uiwebview ios swift wkwebview
虽然UIWebView通过使用来获取cookie 似乎很简单NSHTTPCookieStorage.sharedHTTPCookieStorage(),但它似乎WKWebView将cookie存储在其他地方.
我做了一些研究,然后我从NSHTTPURLResponse对象中抓取了一些饼干.但是,这并不包含以下所用的所有Cookie WKWebView:
func webView(webView: WKWebView, decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse, decisionHandler: (WKNavigationResponsePolicy) -> Void) {
if let httpResponse = navigationResponse.response as? NSHTTPURLResponse {
if let headers = httpResponse.allHeaderFields as? [String: String], url = httpResponse.URL {
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headers, forURL: url)
for cookie in cookies {
logDebug(cookie.description)
logDebug("found cookie " + cookie.name + " " + cookie.value)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是WKWebsiteDataStore,ios 9中还有一个负责管理cookie WKWebView的类,但是,该类不包含检索cookie数据的公共方法:
let storage = WKWebsiteDataStore.defaultDataStore()
storage.fetchDataRecordsOfTypes([WKWebsiteDataTypeCookies], completionHandler: { (records) -> Void in
for record in records {
logDebug("cookie record is " + record.debugDescription)
for dataType in record.dataTypes {
logDebug("data type is " + dataType.debugDescription)
// get cookie data??
}
}
})
Run Code Online (Sandbox Code Playgroud)
是否有获取cookie数据的解决方法?
Ste*_*ntz 65
由它使用(创建)的cookie WKWebView实际上是正确存储在NSHTTPCookieStorage.sharedHTTPCookieStorage().
问题是WKWebView不会立即回写cookie.我认为它按照自己的时间表来做到这一点.例如,当a WKWebView关闭或可能是周期性的.
所以最终他们最终会在那里,但是什么时候不可预测.
您可以NSHTTPCookieStorage通过关闭来强制"共享"到共享WKWebView.如果有效,请告诉我们.
更新:我只记得在Firefox for iOS中,我们强制WKWebView刷新其内部数据,包括cookie,用WKProcessPool新的替换它.没有官方API,但我很确定这是目前最可靠的解决方法.
Tua*_*hou 17
最后,httpCookieStore对于WKWebsiteDataStore在iOS的11降落.
https://developer.apple.com/documentation/webkit/wkwebsitedatastore?changes=latest_minor
Vas*_*huk 17
Xcode 9.2,Swift 4
extension WKWebView {
private var httpCookieStore: WKHTTPCookieStore { return WKWebsiteDataStore.default().httpCookieStore }
func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->()) {
var cookieDict = [String : AnyObject]()
httpCookieStore.getAllCookies { cookies in
for cookie in cookies {
if let domain = domain {
if cookie.domain.contains(domain) {
cookieDict[cookie.name] = cookie.properties as AnyObject?
}
} else {
cookieDict[cookie.name] = cookie.properties as AnyObject?
}
}
completion(cookieDict)
}
}
}
Run Code Online (Sandbox Code Playgroud)
// get cookies for domain
webView.getCookies(for: url.host) { data in
print("=========================================")
print("\(url.absoluteString)")
print(data)
}
// get all cookies
webView.getCookies() { data in
print("=========================================")
print("\(url.absoluteString)")
print(data)
}
Run Code Online (Sandbox Code Playgroud)
- 不要忘记在此处添加解决方案代码
- ViewController嵌入了视图控制器
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Run Code Online (Sandbox Code Playgroud)
小智 9
我知道这是一个非常古老的问题,我们有一个解决方案,但只适用于iOS 11和更高版本.对于那些正在处理iOS 10及更低版本(像我一样)的人,你可以考虑这种方法.它对我来说很完美:
extension WKWebView {
func refreshCookies() {
self.configuration.processPool = WKProcessPool()
// TO DO: Save your cookies,...
}
}
Run Code Online (Sandbox Code Playgroud)
- >这只适用于真实设备.
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
if let response = navigationResponse.response as? HTTPURLResponse,
let allHttpHeaders = response.allHeaderFields as? [String: String],
let responseUrl = response.url {
let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHttpHeaders, for: responseUrl)
for cookie in cookies {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
decisionHandler(.allow)
}
Run Code Online (Sandbox Code Playgroud)
按照Stefan Arentz和Phenom的回答.
小智 5
if (@available(iOS 11.0, *)) {
[webView.configuration.websiteDataStore.httpCookieStore
getAllCookies:^(NSArray<NSHTTPCookie *> *_Nonnull cookies) {
NSURLRequest *request =
[[NSURLRequest alloc] initWithURL:self.URL]; //your URL
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session
dataTaskWithRequest:request
completionHandler:^(NSData *responseData, NSURLResponse *response,
NSError *error) {
//Do Something
}];
[task resume];
[session.configuration.HTTPCookieStorage storeCookies:cookies forTask:task];
}];
}
Run Code Online (Sandbox Code Playgroud)
对于iOS 11,没有任何扩展:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
for cookie in cookies {
//...
}
}
}
Run Code Online (Sandbox Code Playgroud)