Editar solo para iOS 11+
Utilice WKHTTPCookieStore :
let cookie = HTTPCookie(properties: [
.domain: "example.com",
.path: "/",
.name: "MyCookieName",
.value: "MyCookieValue",
.secure: "TRUE",
.expires: NSDate(timeIntervalSinceNow: 31556926)
])!
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
Como los está retirando de HTTPCookeStorage, puede hacer esto:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Respuesta anterior para iOS 10 y abajo
Si necesita que sus cookies se configuren en la solicitud de carga inicial, puede configurarlas en NSMutableURLRequest. Debido a que las cookies son solo un encabezado de solicitud con formato especial, esto se puede lograr así:
WKWebView * webView = /*set up your webView*/
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];
[request addValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;" forHTTPHeaderField:@"Cookie"];
// use stringWithFormat: in the above line to inject your values programmatically
[webView loadRequest:request];
Si necesita posteriores solicitudes de AJAX en la página para configurar sus cookies, esto se puede lograr simplemente usando WKUserScript para establecer los valores mediante programación a través de JavaScript al inicio del documento de la siguiente manera:
WKUserContentController* userContentController = WKUserContentController.new;
WKUserScript * cookieScript = [[WKUserScript alloc]
initWithSource: @"document.cookie = 'TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';"
injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
// again, use stringWithFormat: in the above line to inject your values programmatically
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.new;
webViewConfig.userContentController = userContentController;
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];
La combinación de estas dos técnicas debería proporcionarle herramientas suficientes para transferir valores de cookies de Native App Land a Web View Land. Puede encontrar más información sobre la API de JavaScript de cookies en la página de Mozilla si necesita algunas cookies más avanzadas.
Sí, apesta que Apple no sea compatible con muchas de las sutilezas de UIWebView . No estoy seguro de si alguna vez los apoyarán, pero espero que lo logren pronto. ¡Espero que esto ayude!
Después de jugar con esta respuesta (que fue increíblemente útil :) hemos tenido que hacer algunos cambios:
NSHTTPCookieStorage
Así que modificamos nuestro código para que sea esto;
Crear una solicitud
Esto asegura que la primera solicitud tenga las cookies correctas establecidas, sin enviar ninguna cookie del almacenamiento compartido que sea para otros dominios, y sin enviar cookies seguras a una solicitud insegura.
Manejo de nuevas solicitudes
También debemos asegurarnos de que otras solicitudes tengan configuradas las cookies. Esto se realiza mediante un script que se ejecuta en la carga de documentos que verifica si hay un conjunto de cookies y, si no, configúrelo en el valor
NSHTTPCookieStorage
....
Manejo de cambios de cookies
También tenemos que lidiar con el servidor cambiando el valor de una cookie. Esto significa agregar otro script para volver a llamar desde la vista web que estamos creando para actualizar nuestro
NSHTTPCookieStorage
.e implementando el método delegado para actualizar las cookies que han cambiado, ¡asegurándonos de que solo estamos actualizando las cookies del dominio actual!
Esto parece solucionar nuestros problemas de cookies sin que tengamos que lidiar con cada lugar que usamos WKWebView de manera diferente. Ahora podemos usar este código como ayudante para crear nuestras vistas web y se actualiza de forma transparente
NSHTTPCookieStorage
para nosotros.EDITAR: Resulta que utilicé una categoría privada en NSHTTPCookie; aquí está el código:
fuente
a=b
, terminaría con la cadena de cookiesname=a=b;domain=.example.com;path=/
: creo que el estándar se divide;
y luego se divide en el primero=
en el par clave = valor. Aunque probaría esto :)Las cookies deben establecerse en la configuración antes de que
WKWebView
se cree. De lo contrario, incluso conWKHTTPCookieStore
elsetCookie
controlador de finalización, las cookies no se sincronizarán de manera confiable con la vista web. Esto vuelve a esta línea desde los documentos enWKWebViewConfiguration
Eso
@NSCopying
es una especie de copia profunda. La implementación está más allá de mí, pero el resultado final es que, a menos que establezca cookies antes de inicializar la vista web, no puede contar con las cookies. Esto puede complicar la arquitectura de la aplicación porque la inicialización de una vista se convierte en un proceso asincrónico. Terminarás con algo como estoy luego usarlo como
El ejemplo anterior difiere la creación de vistas hasta el último momento posible, otra solución sería crear la configuración o vista web con mucha anticipación y manejar la naturaleza asincrónica antes de la creación de un controlador de vista.
Una nota final: una vez que crea esta vista web, la ha dejado libre, no puede agregar más cookies sin usar los métodos descritos en esta respuesta . Sin embargo, puede usar la
WKHTTPCookieStoreObserver
API para al menos observar los cambios que ocurren en las cookies. Entonces, si una cookie de sesión se actualiza en la vista web, puede actualizar manualmente el sistemaHTTPCookieStorage
con esta nueva cookie si lo desea.Para más información sobre esto, pase a las 18:00 en este carga de contenido web personalizado de la sesión WWDC 2017 . Al comienzo de esta sesión, hay un ejemplo de código engañoso que omite el hecho de que la vista web debe crearse en el controlador de finalización.
La demostración en vivo a las 18:00 aclara esto.
Editar A partir de Mojave Beta 7 y iOS 12 Beta 7, al menos, veo un comportamiento mucho más consistente con las cookies. El
setCookie(_:)
método incluso parece permitir la configuración de cookies después de queWKWebView
se haya creado. Sin embargo, me pareció importante no tocar laprocessPool
variable en absoluto. La funcionalidad de configuración de cookies funciona mejor cuando no se crean grupos adicionales y cuando esa propiedad se deja sola. Creo que es seguro decir que tuvimos problemas debido a algunos errores en WebKit.fuente
trabaja para mi
fuente
else
condición con la que está llamando aldecisionHandler
cierre, por.cancel
lowebview
que en realidad no carga la solicitud inicial. Después de queloadRequest
se llame a laelse
condición, este método de delegado se volverá a llamar para esa solicitud y entrará en laif
condición porque elCookie
encabezado estará presente.else
condición.Aquí está mi versión de la solución Mattrs en Swift para inyectar todas las cookies de HTTPCookieStorage. Esto se hizo principalmente para inyectar una cookie de autenticación para crear una sesión de usuario.
fuente
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
establecer cookie
eliminar cookie
fuente
Actualización de Swift 3:
fuente
HTTPCookieStorage.shared
?Después de buscar varias respuestas aquí y no tener éxito, revisé la documentación de WebKit y me topé con el
requestHeaderFields
método estáticoHTTPCookie
, que convierte una matriz de cookies en un formato adecuado para un campo de encabezado. La combinación de esto con la idea de Mattr de actualizarURLRequest
antes de cargarlo con los encabezados de las cookies me ayudó a llegar a la meta.Swift 4.1, 4.2, 5.0:
Para hacer esto aún más simple, use una extensión:
Ahora solo se convierte en:
Esta extensión también está disponible en LionheartExtensions si solo desea una solución directa. ¡Salud!
fuente
En iOS 11, puede administrar las cookies ahora :), vea esta sesión: https://developer.apple.com/videos/play/wwdc2017/220/
fuente
La razón detrás de esta respuesta publicada es que probé muchas soluciones, pero ninguna funcionó correctamente, la mayoría de las respuestas no funcionan en caso de que tenga que configurar la cookie la primera vez, y obtuve el resultado de que la cookie no se sincronice la primera vez, use esta solución, funciona para ambos iOS> = 11.0 <= iOS 11 hasta 8.0, también funciona con sincronización de cookies la primera vez.
Para iOS> = 11.0 - Swift 4.2
Obtenga cookies http y configúrelas en wkwebview la tienda de cookies esta manera, es un punto muy complicado cargar su solicitud en wkwebview , debe enviar una solicitud de carga cuando las cookies se configurarán por completo, esta es la función que escribí.
Llame a la función con el cierre finalizado. Llame cargar webview. FYI esta función solo maneja iOS> = 11.0
Aquí está la implementación de la función syncCookies .
Para iOS 8 hasta iOS 11
necesita configurar algunas cosas adicionales que necesita para configurar dos cookies una vez usando WKUserScript y no olvide agregar las cookies también, de lo contrario, su cookie no se sincronizará la primera vez y verá que su página no se carga correctamente la primera vez. este es el diablo que encontré para admitir cookies para iOS 8.0
antes de Wkwebview creación de objetos.
Concéntrese en esta función getJSCookiesString
Aquí hay otro paso: wkuserscript no sincroniza las cookies de inmediato, hay que cargar mucho la primera página con la cookie, una es volver a cargar la vista web si finaliza el proceso, pero no recomiendo usarla, no es bueno para el punto de vista del usuario , diablos, siempre que esté listo para cargar las cookies de conjunto de solicitudes en el encabezado de la solicitud y de esta manera, no olvide agregar la verificación de la versión de iOS. antes de la solicitud de carga, llame a esta función.
escribí extensión para URLRequest
ahora estás listo para probar iOS> 8
fuente
Encuentre la solución que probablemente funcione para usted de manera inmediata. Básicamente está modificado y actualizado para la respuesta de Swift 4 @ user3589213 .
fuente
He intentado todas las respuestas anteriores pero ninguna de ellas funciona. Después de tantos intentos, finalmente encontré una forma confiable de configurar la cookie WKWebview.
Primero debe crear una instancia de WKProcessPool y configurarla en la WKWebViewConfiguration que se utilizará para inicializar la propia WkWebview:
Configurar WKProcessPool es el paso más importante aquí.WKWebview hace uso del aislamiento de procesos, lo que significa que se ejecuta en un proceso diferente al proceso de su aplicación. Esto a veces puede causar conflictos y evitar que su cookie se sincronice correctamente con WKWebview.
Ahora veamos la definición de WKProcessPool
Preste atención a la última oración si planea usar la misma WKWebview para solicitudes de subsecuencia
lo que quiero decir es que si no usa la misma instancia de WKProcessPool cada vez que configura un WKWebView para el mismo dominio (tal vez tenga un VC A que contenga un WKWebView y desee crear diferentes instancias de VC A en diferentes lugares ), puede haber conflictos al configurar las cookies. Para resolver el problema, después de la primera creación de WKProcessPool para un WKWebView que carga el dominio B, lo guardo en un singleton y uso ese mismo WKProcessPool cada vez que tengo que crear un WKWebView que carga el mismo dominio B
Después del proceso de inicialización, puede cargar una URLRequest dentro del bloque de finalización de
httpCookieStore.setCookie
. Aquí, debe adjuntar la cookie al encabezado de la solicitud contrario, no funcionará.P / s: robé la extensión de la fantástica respuesta anterior de Dan Loewenherz
fuente
Mi versión de la respuesta de nteiss. Probado en
iOS 11, 12, 13
. Parece que no tienen que utilizarDispatchGroup
eniOS 13
más.Yo uso la función no estática
includeCustomCookies
sobreWKWebViewConfiguration
, de modo que pueda actualizarcookies
cada vez que crear nuevasWKWebViewConfiguration
.Entonces lo uso así:
fuente
Aquí se muestra la mejor solución para las solicitudes XHR
Versión Swift 4:
fuente
Si alguien está usando Alamofire, entonces esta es una mejor solución.
fuente
Esto funciona para mí: después de configurar las cookies, agregue fetchdatarecords
fuente
Al agregar múltiples elementos de cookies, puede hacerlo así: (
path
ydomain
se requiere para cada elemento)de lo contrario, solo se establecerá el primer elemento de cookie.
fuente
También puede usar WKWebsiteDataStore para obtener un comportamiento similar a HTTPCookieStorage de UIWebView.
fuente
El siguiente código funciona bien en mi proyecto Swift5. intente cargar url por WKWebView a continuación:
fuente
Esta es mi solución para manejar con Cookies y WKWebView en iOS 9 o posterior.
fuente
El error que estaba cometiendo es que estaba pasando toda la URL en el atributo de dominio, debería ser solo el nombre de dominio.
fuente