Puis-je définir des cookies soient utilisés par un WKWebView?
Je suis en train de basculer d'une application existante de UIWebView
à WKWebView
. Cette application gère les utilisateurs de connexion /session à l'extérieur de la webview
et définit la cookies
requis pour l'authentification dans le NSHTTPCookieStore
. Malheureusement, de nouveaux WKWebView
ne pas utiliser le cookies
de la NSHTTPCookieStorage
. Est-il une autre façon d'atteindre cet objectif?
Vous devez vous connecter pour publier un commentaire.
Modifier pour iOS 11+ seulement
Utilisation WKHTTPCookieStore:
Depuis que vous êtes en tirant de HTTPCookeStorage, vous pouvez le faire:
Vieille réponse pour iOS 10 et au-dessous de
Si vous avez besoin de vos cookies sur le chargement initial de demande, vous pouvez les mettre sur NSMutableURLRequest. Parce que les cookies sont tout spécialement formaté en-tête de demande ceci peut être réalisé comme suit:
Si vous avez besoin ultérieur des requêtes AJAX sur la page de ont leur des cookies, cela peut être réalisé en utilisant simplement WKUserScript pour définir les valeurs par programmation via javascript document de commencer comme ça:
La combinaison de ces deux techniques devrait vous donner suffisamment d'outils pour le transfert de la valeur du cookie d'Application Native Land pour l'Affichage Web des Terres. Vous trouverez plus d'infos sur le témoin de l'API javascript sur la page de Mozilla si vous avez besoin de plus avancé des cookies.
Ouais, c'est nul qu'Apple n'est pas de soutenir de nombreux de les subtilités de la UIWebView. Vous ne savez pas si ils seront toujours les soutenir, mais j'espère qu'ils vont le faire bientôt. Espérons que cette aide!
Après avoir joué avec cette réponse (qui a été incroyablement utile 🙂 nous avons dû faire quelques modifications:
NSHTTPCookieStorage
Nous avons modifié notre code à l'être;
Création d'une demande
Cela permet de s'assurer que la première demande a la bonne cookies, sans l'envoi de cookies pour le stockage partagé qui sont pour d'autres domaines, et sans envoyer de sécuriser les cookies dans une insécurité demande.
Traiter avec demande en outre à
Nous avons également besoin de s'assurer que les autres demandes ont les cookies. Ceci est fait en utilisant un script qui s'exécute sur le document de la charge qui vérifie si il y a un cookie ensemble et si non, mettez-la en valeur en
NSHTTPCookieStorage
....
Traiter avec cookie changements
Nous avons également besoin de traiter avec le serveur de la modification d'une valeur du cookie. Cela signifie l'ajout d'un autre script pour appeler à nouveau hors de la vue web nous créons pour mettre à jour notre
NSHTTPCookieStorage
.et la mise en œuvre de la méthode du délégué de mettre à jour tous les témoins qui ont changé, vous assurant que nous ne sommes que de la mise à jour des cookies à partir du domaine actuel!
Ce qui semble fixer notre cookie problèmes sans que nous ayons à faire face à chaque endroit que nous utilisons WKWebView différemment. Nous pouvons maintenant suffit d'utiliser ce code comme une aide pour créer notre web vues et de manière transparente mises à jour
NSHTTPCookieStorage
pour nous.EDIT: s'avère que j'ai utilisé un privé de la catégorie sur NSHTTPCookie - voici le code:
a=b
vous vous retrouvez avec le cookie chaînename=a=b;domain=.example.com;path=/
- je crois que la norme se divise sur;
puis se divise sur le premier=
dans la clé=valeur paire. Je voudrais tester ce bien 🙂Les cookies doivent être définies sur la configuration avant de l'
WKWebView
est créé. Sinon, même avecWKHTTPCookieStore
'ssetCookie
gestionnaire d'achèvement, les cookies ne sera pas sûrement être synchronisés à la vue web. Cela remonte à cette ligne du docs surWKWebViewConfiguration
Que
@NSCopying
est un peu une copie en profondeur. La mise en œuvre est au delà de moi, mais le résultat final est que si vous définissez des cookies avant l'initialisation de la webview, vous ne pouvez pas compter sur les témoins d'être là. Cela peut compliquer l'application architecture, du fait de l'initialisation d'une vue devient un processus asynchrone. Vous obtiendrez quelque chose comme ceciet puis de l'utiliser quelque chose comme
L'exemple ci-dessus diffère de la création de la vue jusqu'au dernier moment possible, une autre solution serait de créer la config ou webview bien à l'avance et gérer la nature asynchrone, avant la création d'un point de vue contrôleur.
Une dernière remarque: une fois que vous créez ce webview, vous avez défini un lâche dans la nature, vous ne pouvez pas ajouter plus de cookies sans l'aide des méthodes décrites dans cette réponse. Vous pouvez cependant utiliser le
WKHTTPCookieStoreObserver
api pour au moins observer les changements qui se produisent à des cookies. Donc, si un cookie de session est mise à jour dans la webview, vous pouvez mettre à jour manuellement le système deHTTPCookieStorage
avec ce nouveau cookie si vous le souhaitez.Pour en savoir plus, passez à 18:00, à cette 2017 de la WWDC Session Personnalisée de Contenu Web de Chargement. Au début de cette session, il est trompeur exemple de code qui omet le fait que la webview doit être créé dans le gestionnaire d'achèvement.
La démo live à 18:00 précise cette.
Modifier de Mojave Beta 7 et iOS 12 Beta 7, au moins, je vois beaucoup plus un comportement cohérent avec les cookies. Le
setCookie(_:)
méthode, même apparaît pour permettre la mise cookies après laWKWebView
a été créé. Je n'ai trouver qu'il est important de bien, à pas toucher laprocessPool
variable à tous. Le témoin de réglage de la fonctionnalité qui fonctionne le mieux, quand aucun autre piscines sont créés et lorsque cette propriété est laissé seul. Je pense qu'il est sûr de dire que nous avons d'avoir des problèmes à cause de certains bugs dans WebKit.travail pour moi
else
condition qu'il appelle ladecisionHandler
fermeture avec.cancel
de sorte que lewebview
ne fait pas de charge à la demande initiale. Après laloadRequest
est appelé dans laelse
état de ce délégué méthode sera appelée de nouveau à cette demande et dans laif
parce que lesCookie
en-tête sera présent.else
condition.AppDelegate.m
?Voici ma version de Mattrs solution rapide pour l'injection de tous les cookies de HTTPCookieStorage. Cela a été fait principalement pour injecter un cookie d'authentification pour créer une session utilisateur.
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
Swift 3 mise à jour :
HTTPCookieStorage.shared
ainsi?cookie ensemble
supprimer cookie
Dans iOS 11, vous pouvez gérer les cookies maintenant :), voir cette session: https://developer.apple.com/videos/play/wwdc2017/220/
Après en regardant à travers les différentes réponses ici et n'ayant pas eu de succès, j'ai passé au peigne fin le WebKit de la documentation et je suis tombé sur le
requestHeaderFields
méthode statique surHTTPCookie
, qui convertit un tableau de cookies dans un format approprié pour un champ d'en-tête. En combinant ceci avec mattr insight de la mise à jour de laURLRequest
avant de le charger avec le cookie en-têtes de m'par le biais de la ligne d'arrivée.Swift 4.1, 4.2, 5.0:
Pour que ce soit encore plus simple, l'utilisation d'une extension:
Maintenant, il devient tout simplement:
Cette extension est également disponible dans LionheartExtensions si vous voulez juste une goutte dans la solution. Cheers!
La raison derrière posté cette réponse, c'est que j'ai essayé beaucoup de solution mais aucune ne fonctionne correctement, la plupart de la réponse fonctionne pas dans les cas où ont pour placer le biscuit première fois, et a obtenu le résultat cookie de ne pas synchroniser première fois, Veuillez utiliser cette solution de travail à la fois pour iOS >= 11.0 <= iOS 11 jusqu'à 8.0, travaillent également avec témoin de synchronisation première fois.
Pour iOS >= 11.0
-- Swift 4.2
Obtenir cookies http et mis en wkwebview banque de cookies comme de cette façon, il est très difficile du point de charger votre demande en wkwebview, doit envoyé la demande pour le chargement lorsque des cookies va être mis complètement, voici la fonction que j'ai écrit.
Appel de la fonction avec fermeture à la fin, vous appeler charge webview. Pour info cette fonction uniquement de la poignée iOS >= 11.0
Ici est mise en œuvre pour syncCookies fonction.
Pour iOS 8 à iOS 11
vous avez besoin pour l'installation de certaines choses supplémentaires que vous devez définir deux fois que des cookies l'un à travers l'utilisation de WKUserScript et n'oubliez pas d'ajouter des cookies dans la demande aussi bien, sinon, votre cookie de ne pas synchroniser premier temps et vous permettra de voir la page se charge pas de la première heure correctement. c'est le diable que j'ai trouvé à l'appui de cookies pour iOS 8.0
avant de vous Wkwebview de création de l'objet.
L'accent sur cette fonction getJSCookiesString
Ici est autre étape wkuserscript de ne pas synchroniser les cookies immédiatement, il ya beaucoup de diable pour charger la première page de temps avec un cookie est pour recharger webview nouveau, si elle arrêter le processus, mais je ne recommande pas de l'utiliser, il n'est pas bon pour l'utilisateur, point de vue, le diable est à chaque fois que vous prêt pour le chargement de demande de définir des cookies en-tête de la requête en tant que bien comme ça, n'oubliez pas d'ajouter la version iOS de vérifier. avant de charger demande d'appeler cette fonction.
j'ai écrit extension pour URLRequest
maintenant vous prêt à aller pour tester iOS > 8
Veuillez trouver la solution la plus probable pour vous sortir de la boîte. Fondamentalement, il est modifié et mis à jour pour Swift 4 @user3589213's réponse.
La meilleure correction pour les demandes XHR est montré ici
Swift 4 version:
Si quelqu'un est à l'aide de Alamofire, alors c'est la meilleure solution.
Cela fonctionne pour moi:
Après setcookies , ajouter fetchdatarecords
J'ai essayé toutes les réponses ci-dessus, mais aucune de ces travaux. Après de nombreuses tentatives j'ai enfin trouvé un moyen fiable pour définir WKWebview cookie.
Vous devez d'abord créer une instance de WKProcessPool et WKWebViewConfiguration qui est utilisé pour initialiser la WkWebview lui-même:
Réglage WKProcessPool est l'étape la plus importante ici. WKWebview rend l'utilisation de l'isolation des processus - ce qui signifie qu'il s'exécute sur un autre processus que le processus de votre application. Cela peut parfois créer des conflits et d'éviter que vos cookies soient synchronisés correctement avec le WKWebview.
Maintenant, regardons la définition de WKProcessPool
Prêter attention à la dernière phrase, si vous prévoyez d'utiliser le même WKWebview pour la sous-suite demandes
ce que je signifie, 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 vous avez CR UNE qui contient un WKWebView et vous souhaitez créer différentes instances de CR UN dans des lieux différents), il peut y avoir conflit cookies. Pour résoudre le problème, après la première création de la WKProcessPool pour un WKWebView qui charge le domaine B, je l'enregistre dans un singleton et utilisez la 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 à l'intérieur de l'achèvement du bloc de
httpCookieStore.setCookie
. Ici, , vous devez joindre le cookie à la tête de la demande sinon ça ne marche pas.P/s: j'ai volé l'extension de la formidable réponse ci-dessus par Dan Loewenherz
Lors de l'ajout de multiplier cookie éléments, vous pouvez le faire comme ceci: (
path
&domain
est requise pour chaque élément)contraire, seul le premier élément de cookie sera fixé.
Vous pouvez également utiliser WKWebsiteDataStore pour obtenir un comportement similaire à HTTPCookieStorage de UIWebView.