Modifier uniquement pour iOS 11+
Utilisez 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)
Puisque vous les récupérez de HTTPCookeStorage, vous pouvez faire ceci:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Ancienne réponse pour iOS 10 et inférieur
Si vous souhaitez que vos cookies soient définis lors de la demande de chargement initiale, vous pouvez les définir sur NSMutableURLRequest. Comme les cookies ne sont qu'un en-tête de requête spécialement formaté, cela peut être réalisé comme suit:
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 vous avez besoin de requêtes AJAX ultérieures sur la page pour que leurs cookies soient définis, cela peut être réalisé en utilisant simplement WKUserScript pour définir les valeurs par programme via javascript au démarrage du document comme ceci:
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 combinaison de ces deux techniques devrait vous donner suffisamment d'outils pour transférer les valeurs des cookies de Native App Land vers Web View Land. Vous pouvez trouver plus d'informations sur l' API javascript cookie sur la page de Mozilla si vous avez besoin de cookies plus avancés.
Oui, ça craint qu'Apple ne prenne pas en charge la plupart des subtilités d'UIWebView . Je ne sais pas s'ils les soutiendront un jour, mais j'espère qu'ils le feront bientôt. J'espère que cela t'aides!
Après avoir joué avec cette réponse (qui était extrêmement utile :), nous avons dû faire quelques changements:
NSHTTPCookieStorage
Nous avons donc modifié notre code pour être ceci;
Créer une demande
Cela garantit que la première demande a les bons cookies définis, sans envoyer de cookies du stockage partagé qui sont pour d'autres domaines, et sans envoyer de cookies sécurisés dans une demande non sécurisée.
Traiter d'autres demandes
Nous devons également nous assurer que les autres demandes ont les cookies définis. Cela se fait à l'aide d'un script qui s'exécute lors du chargement du document qui vérifie s'il existe un ensemble de cookies et, dans le cas contraire, définissez-le sur la valeur dans
NSHTTPCookieStorage
....
Gérer les changements de cookies
Nous devons également faire en sorte que le serveur modifie la valeur d'un cookie. Cela signifie ajouter un autre script pour rappeler la vue Web que nous créons pour mettre à jour notre
NSHTTPCookieStorage
.et implémenter la méthode déléguée pour mettre à jour tous les cookies qui ont changé, en s'assurant que nous ne mettons à jour que les cookies du domaine actuel!
Cela semble résoudre nos problèmes de cookies sans que nous ayons à traiter différemment chaque endroit où nous utilisons WKWebView. Nous pouvons maintenant simplement utiliser ce code comme une aide pour créer nos vues Web et il se met
NSHTTPCookieStorage
à jour de manière transparente pour nous.EDIT: Il s'avère que j'ai utilisé une catégorie privée sur NSHTTPCookie - voici le code:
la source
a=b
vous vous retrouveriez avec la chaîne de cookiename=a=b;domain=.example.com;path=/
- je crois que la norme se;
divise puis se divise en premier=
dans la paire clé = valeur. JeLes cookies doivent être définis sur la configuration avant la
WKWebView
création de. Sinon, même avecWKHTTPCookieStore
lesetCookie
gestionnaire de complétion de, les cookies ne seront pas synchronisés de manière fiable avec la vue Web. Cela revient à cette ligne de la documentation surWKWebViewConfiguration
C'est en
@NSCopying
quelque sorte une copie profonde. L'implémentation me dépasse, mais le résultat final est qu'à moins de définir des cookies avant d'initialiser la vue Web, vous ne pouvez pas compter sur la présence des cookies. Cela peut compliquer l'architecture de l'application, car l'initialisation d'une vue devient un processus asynchrone. Tu finiras avec quelque chose comme çapuis pour l'utiliser quelque chose comme
L'exemple ci-dessus reporte la création de la vue jusqu'au dernier moment possible, une autre solution serait de créer la configuration ou la vue Web bien à l'avance et de gérer la nature asynchrone avant la création d'un contrôleur de vue.
Une dernière remarque: une fois que vous avez créé cette vue Web, vous l'avez libérée dans la nature, vous ne pouvez pas ajouter plus de cookies sans utiliser les méthodes décrites dans cette réponse . Vous pouvez cependant utiliser l'
WKHTTPCookieStoreObserver
API pour au moins observer les modifications apportées aux cookies. Ainsi, si un cookie de session est mis à jour dans la vue Web, vous pouvez mettre à jour manuellement le systèmeHTTPCookieStorage
avec ce nouveau cookie si vous le souhaitez.Pour en savoir plus, passez à 18h00 à ce chargement de contenu Web personnalisé de la session WWDC 2017 . Au début de cette session, il existe un exemple de code trompeur qui omet le fait que la vue Web doit être créée dans le gestionnaire d'achèvement.
La démo en direct à 18h00 clarifie cela.
Modifier À partir de Mojave Beta 7 et iOS 12 Beta 7 au moins, je constate un comportement beaucoup plus cohérent avec les cookies. La
setCookie(_:)
méthode semble même autoriser la configuration de cookies après laWKWebView
création de. J'ai cependant trouvé important de ne pas toucher duprocessPool
tout à la variable. La fonctionnalité de configuration des cookies fonctionne mieux lorsqu'aucun pool supplémentaire n'est créé et lorsque cette propriété est laissée seule. Je pense qu'il est prudent de dire que nous avons eu des problèmes en raison de certains bogues dans WebKit.la source
travaille pour moi
la source
else
condition avec laquelle il appelle ladecisionHandler
fermeture pour.cancel
que lewebview
ne charge pas réellement la requête initiale. Une fois que leloadRequest
est appelé dans laelse
condition, cette méthode déléguée sera à nouveau appelée pour cette demande et elle passera dans laif
condition car l'en-Cookie
tête sera présent.else
condition.Voici ma version de la solution Mattrs dans Swift pour injecter tous les cookies de HTTPCookieStorage. Cela a été fait principalement pour injecter un cookie d'authentification pour créer une session utilisateur.
la source
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
définir un cookie
supprimer le cookie
la source
Mise à jour de Swift 3:
la source
HTTPCookieStorage.shared
?Après avoir parcouru diverses réponses ici et sans succès, j'ai parcouru la documentation WebKit et suis tombé sur la
requestHeaderFields
méthode statiqueHTTPCookie
, qui convertit un tableau de cookies dans un format adapté à un champ d'en-tête. En combinant cela avec la vision de mattr de la mise à jourURLRequest
avant de le charger avec les en-têtes de cookie m'a permis de franchir la ligne d'arrivée.Swift 4.1, 4.2, 5.0:
Pour rendre cela encore plus simple, utilisez une extension:
Maintenant, cela devient simplement:
Cette extension est également disponible dans LionheartExtensions si vous souhaitez simplement une solution intégrée. À votre santé!
la source
Sous iOS 11, vous pouvez gérer les cookies maintenant :), voir cette session: https://developer.apple.com/videos/play/wwdc2017/220/
la source
La raison derrière la publication de cette réponse est que j'ai essayé de nombreuses solutions mais personne ne fonctionne correctement, la plupart de la réponse ne fonctionne pas dans le cas où vous devez définir un cookie pour la première fois et que le cookie de résultat ne se synchronise pas la première fois, veuillez utiliser cette solution, cela fonctionne pour les deux iOS> = 11.0 <= iOS 11 à 8.0, fonctionne également avec la synchronisation des cookies pour la première fois.
Pour iOS> = 11,0 - Swift 4.2
Obtenez des cookies http et définissez-les dans le magasin de cookies wkwebview de cette manière, il est très difficile de charger votre demande dans wkwebview , vous devez envoyer une demande de chargement lorsque les cookies seront complètement définis, voici la fonction que j'ai écrite.
Appelez la fonction avec la fermeture à la fin que vous appelez load webview. Pour info, cette fonction ne gère que iOS> = 11.0
Voici l'implémentation de la fonction syncCookies .
Pour iOS 8 à iOS 11
vous devez configurer certaines choses supplémentaires dont vous avez besoin pour définir deux cookies temporels un en utilisant WKUserScript et n'oubliez pas d'ajouter également des cookies dans la demande, sinon votre cookie ne se synchronise pas la première fois et vous verrez que votre page ne se charge pas correctement la première fois. c'est le diable que j'ai trouvé pour prendre en charge les cookies pour iOS 8.0
avant de créer un objet Wkwebview.
Focus sur cette fonction getJSCookiesString
Voici une autre étape wkuserscript ne synchronise pas les cookies immédiatement, il y a beaucoup de mal à charger la première page avec le cookie, l'un est de recharger à nouveau la vue Web si elle met fin au processus mais je ne recommande pas de l'utiliser, ce n'est pas bon pour le point de vue de l'utilisateur , diable est que chaque fois que vous êtes prêt à charger des cookies de demande dans l'en-tête de la demande, n'oubliez pas d'ajouter la vérification de la version iOS. avant la demande de chargement, appelez cette fonction.
j'ai écrit une extension pour URLRequest
vous êtes maintenant prêt à tester iOS> 8
la source
Veuillez trouver la solution qui fonctionnera le plus pour vous dès sa sortie de la boîte. Fondamentalement , il est modifié et mis à jour pour Swift 4 @ user3589213 de réponse .
la source
J'ai essayé toutes les réponses ci-dessus mais aucune d'elles ne fonctionne. Après tant de tentatives, j'ai enfin trouvé un moyen fiable de définir le cookie WKWebview.
Vous devez d'abord créer une instance de WKProcessPool et la définir sur WKWebViewConfiguration qui doit être utilisée pour initialiser le WkWebview lui-même:
La configuration de WKProcessPool est l'étape la plus importante ici. WKWebview utilise l'isolation de processus - ce qui signifie qu'il s'exécute sur un processus différent de celui de votre application. Cela peut parfois provoquer des conflits et empêcher votre cookie d'être correctement synchronisé avec WKWebview.
Regardons maintenant la définition de WKProcessPool
Faites attention à la dernière phrase si vous prévoyez d'utiliser le même WKWebview pour les demandes de sous-séquences
ce que je veux dire, c'est que si vous n'utilisez pas la même instance de WKProcessPool à chaque fois que vous configurez un WKWebView pour le même domaine (peut-être que vous avez un VC A qui contient un WKWebView et que vous souhaitez créer différentes instances de VC A à différents endroits ), il peut y avoir des cookies de paramétrage de conflit. Pour résoudre le problème, après la première création du WKProcessPool pour un WKWebView qui charge le domaine B, je l'enregistre dans un singleton et utilise ce même WKProcessPool chaque fois que je dois créer un WKWebView qui charge le même domaine B
Après le processus d'initialisation, vous pouvez charger une URLRequest dans le bloc de complétion de
httpCookieStore.setCookie
. Ici, vous devez attacher le cookie à l'en-tête de la demande sinon cela ne fonctionnera pas.P / s: J'ai volé l'extension de la réponse fantastique ci-dessus de Dan Loewenherz
la source
Ma version de la réponse de nteiss. Testé sur
iOS 11, 12, 13
. On dirait que vous n'avez pas à utiliserDispatchGroup
suriOS 13
plus.J'utilise la fonction non statique
includeCustomCookies
surWKWebViewConfiguration
, afin que je puisse mettre à jourcookies
chaque fois que je crée de nouveauxWKWebViewConfiguration
.Ensuite, je l'utilise comme ceci:
la source
Le meilleur correctif pour les demandes XHR est montré ici
Version Swift 4:
la source
Si quelqu'un utilise Alamofire, c'est la meilleure solution.
la source
Cela fonctionne pour moi: après avoir défini les cookies, ajoutez fetchdatarecords
la source
Lors de l'ajout d'éléments multi-cookies, vous pouvez le faire comme ceci: (
path
&domain
est requis pour chaque élément)sinon, seul le premier élément de cookie sera défini.
la source
Vous pouvez également utiliser WKWebsiteDataStore pour obtenir un comportement similaire à HTTPCookieStorage à partir d'UIWebView.
la source
Le code ci-dessous fonctionne bien dans mon projet Swift5. essayez de charger l'url par WKWebView ci-dessous:
la source
C'est ma solution pour gérer les cookies et WKWebView sous iOS 9 ou version ultérieure.
la source
Cette erreur que je faisais est que je passais l'URL entière dans l'attribut de domaine, ce ne devrait être que le nom de domaine.
la source