Obtener todas las cookies de WKWebView

mientras que get cookies de UIWebView parece sencillo al usar NSHTTPCookieStorage.shanetworkingHTTPCookieStorage() , parece que WKWebView almacena las cookies en otro lugar.

Hice un poco de investigación, y pude get algunas cookies del object de NSHTTPURLResponse de NSHTTPURLResponse . Sin embargo, esto no contiene todas las cookies utilizadas por 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) } } } } 

Curiosamente, también hay una class WKWebsiteDataStore en ios 9 que es responsable de administrar las cookies en WKWebView , sin embargo, la class no contiene un método público para recuperar los datos de las cookies:

 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?? } } 

¿Hay alguna solución para get los datos de las cookies?

Finalmente, httpCookieStore para WKWebsiteDataStore aterrizó en iOS 11.

https://developer.apple.com/documentation/webkit/wkwebsitedatastore?changes=latest_minor

Las cookies utilizadas (creadas) por el WKWebView se almacenan correctamente en el NSHTTPCookieStorage.shanetworkingHTTPCookieStorage() .

El problema es que WKWebView no devuelve las cookies de inmediato. Creo que hace esto en su propio horario. Por ejemplo, cuando un WKWebView está cerrado o tal vez periódicamente.

Entonces eventualmente terminan allí, pero cuando es impnetworkingecible.

Es posible forzar una 'synchronization' en el NSHTTPCookieStorage compartido cerrando su WKWebView . Por favor, háganos saber si esto funciona.

Actualización : Acabo de recordar que en Firefox para iOS WKWebView a WKWebView a eliminar sus datos internos, incluidas las cookies, reemplazando su WKProcessPool por uno nuevo. No existe una API oficial, pero estoy seguro de que es la solución más confiable en este momento.

Como mencionó Stefan, las cookies se almacenan en NSHTTPCookieStorage.shanetworkingHTTPCookieStorage()

Sin embargo, de mis experimentos, descubrí que las cookies de session establecidas por el server no son visibles para NSHTTPCookieStorage.shanetworkingHTTPCookieStorage() .

Mientras cada WKWebView comparta la misma instancia de WKProcessPool , esas cookies de session se enviarán de vuelta al server para cada request. Si cambia la agrupación de processs para una WKWebView , básicamente está eliminando las cookies de session para todas las requestes futuras.

En la práctica, encontré en el método "decidePolicyForNavigationResponse", puedes usar la siguiente manera para get cookies, pero lo triste es que no es una list completa / completa para una session.

 let response = navigationResponse.response as! NSHTTPURLResponse let headFields = response.allHeaderFields as! [String:String] let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headFields, forURL: response.URL!) 

Esta publicación tiene información útil sobre el event handling cookies con WKWebView. De acuerdo con esto, debería ser capaz de establecer y recuperar cookies utilizando el estándar NSURLCache y NSHTTPCookie. También se refiere a usar WKProccessPool según el comentario de Stephan.

En NSHTTPCookie.cookiesWithResponseHeaderFields(headers, forURL: url) , ¿qué sucede si la url donde están establecidas las cookies no es una url de respuesta de navigation (url que provoca una navigation)? Noto que la URL de callback donde se establecen las cookies nunca se invoca en decidePolicyFor navigationResponse.

 func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { let response = navigationResponse.response as! HTTPURLResponse let cookies = HTTPCookie.cookies(withResponseHeaderFields: response.allHeaderFields as! [String : String], for: response.url!) } 

El delegado anterior nunca se ejecuta para la url de callback, ya que la callback en sí no provoca una navigation de página.

cookies (withResponseHeaderFields: for 🙂