Nur für iOS 11+ bearbeiten
Verwenden Sie 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)
Da Sie sie von HTTPCookeStorage abrufen, können Sie Folgendes tun:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Alte Antwort für iOS 10 und niedriger
Wenn Sie möchten, dass Ihre Cookies bei der ersten Ladeanforderung gesetzt werden, können Sie sie bei NSMutableURLRequest setzen. Da Cookies nur ein speziell formatierter Anforderungsheader sind, kann dies folgendermaßen erreicht werden:
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];
Wenn nachfolgende AJAX-Anforderungen auf der Seite ihre Cookies setzen müssen, können Sie dies einfach mit WKUserScript erreichen, um die Werte beim Start des Dokuments programmgesteuert über Javascript wie folgt festzulegen:
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];
Durch die Kombination dieser beiden Techniken sollten Sie über genügend Tools verfügen, um Cookie-Werte von Native App Land in Web View Land zu übertragen. Weitere Informationen zur Cookie-Javascript-API finden Sie auf der Mozilla-Seite, wenn Sie erweiterte Cookies benötigen.
Ja, es ist schade , dass Apple viele der Feinheiten von UIWebView nicht unterstützt . Ich bin mir nicht sicher, ob sie sie jemals unterstützen werden, aber hoffentlich werden sie es bald schaffen. Hoffe das hilft!
Nachdem wir mit dieser Antwort gespielt hatten (was fantastisch hilfreich war :), mussten wir einige Änderungen vornehmen:
NSHTTPCookieStorage
Also haben wir unseren Code so geändert;
Anfrage erstellen
Dadurch wird sichergestellt, dass für die erste Anforderung die richtigen Cookies gesetzt sind, ohne dass Cookies aus dem gemeinsam genutzten Speicher für andere Domänen gesendet werden und ohne dass sichere Cookies an eine unsichere Anforderung gesendet werden.
Bearbeitung weiterer Anfragen
Wir müssen auch sicherstellen, dass für andere Anfragen die Cookies gesetzt sind. Dies erfolgt mithilfe eines Skripts, das beim Laden des Dokuments ausgeführt wird und prüft, ob ein Cookie-Set vorhanden ist. Wenn nicht, setzen Sie es auf den Wert in
NSHTTPCookieStorage
....
Umgang mit Cookie-Änderungen
Wir müssen uns auch damit befassen, dass der Server den Wert eines Cookies ändert. Dies bedeutet, dass Sie ein weiteres Skript hinzufügen, um aus der von uns erstellten Webansicht zurückzurufen und unsere zu aktualisieren
NSHTTPCookieStorage
.und Implementieren der Delegate-Methode zum Aktualisieren geänderter Cookies, um sicherzustellen, dass nur Cookies von der aktuellen Domain aktualisiert werden!
Dies scheint unsere Cookie-Probleme zu beheben, ohne dass wir mit jedem Ort, an dem wir WKWebView verwenden, anders umgehen müssen. Wir können diesen Code jetzt nur als Hilfsmittel zum Erstellen unserer Webansichten verwenden und er wird
NSHTTPCookieStorage
für uns transparent aktualisiert .BEARBEITEN: Es stellte sich heraus, dass ich eine private Kategorie für NSHTTPCookie verwendet habe - hier ist der Code:
quelle
a=b
wäre, würden Sie am Ende die Cookie-Zeichenfolge erhaltenname=a=b;domain=.example.com;path=/
- ich glaube, dass sich der Standard auf;
und dann auf den ersten=
im Schlüssel = Wert-Paar aufteilt. Ich würde dies allerdings testen :)Die Cookies müssen in der Konfiguration gesetzt werden, bevor das
WKWebView
erstellt wird. Andernfalls werden die Cookies selbst mitWKHTTPCookieStore
demsetCookie
Completion-Handler nicht zuverlässig mit der Webansicht synchronisiert. Dies geht ab den Dokumenten auf diese Zeile zurückWKWebViewConfiguration
Das
@NSCopying
ist eine tiefe Kopie. Die Implementierung ist mir ein Rätsel, aber das Endergebnis ist, dass Sie nicht darauf zählen können, dass die Cookies vorhanden sind, wenn Sie vor dem Initialisieren der Webansicht keine Cookies setzen. Dies kann die App-Architektur komplizieren, da das Initialisieren einer Ansicht zu einem asynchronen Prozess wird. Sie werden mit so etwas endenund dann so etwas zu benutzen
Das obige Beispiel verschiebt die Erstellung von Ansichten bis zum letztmöglichen Moment. Eine andere Lösung besteht darin, die Konfiguration oder Webansicht frühzeitig zu erstellen und die asynchrone Natur vor der Erstellung eines Ansichtscontrollers zu behandeln.
Ein letzter Hinweis: Sobald Sie diese Webansicht erstellt haben, können Sie keine weiteren Cookies mehr hinzufügen, ohne die in dieser Antwort beschriebenen Methoden zu verwenden . Sie können die
WKHTTPCookieStoreObserver
API jedoch verwenden , um zumindest Änderungen an Cookies zu beobachten. Wenn also ein Sitzungscookie in der Webansicht aktualisiert wird, können Sie das SystemHTTPCookieStorage
bei Bedarf manuell mit diesem neuen Cookie aktualisieren .Weitere Informationen hierzu finden Sie in dieser WWDC-Sitzung 2017 zum Laden von benutzerdefinierten Webinhalten bis 18:00 Uhr . Zu Beginn dieser Sitzung gibt es ein irreführendes Codebeispiel, bei dem die Tatsache weggelassen wird, dass die Webansicht im Abschlusshandler erstellt werden sollte.
Die Live-Demo um 18:00 Uhr verdeutlicht dies.
Bearbeiten Ab Mojave Beta 7 und iOS 12 Beta 7 sehe ich ein viel konsistenteres Verhalten mit Cookies. Die
setCookie(_:)
Methode scheint sogar das Setzen von Cookies zu ermöglichen, nachdem dasWKWebView
erstellt wurde. Ich fand es jedoch wichtig, die Variable überhaupt nicht zu berührenprocessPool
. Die Cookie-Einstellungsfunktion funktioniert am besten, wenn keine zusätzlichen Pools erstellt werden und diese Eigenschaft gut in Ruhe gelassen wird. Ich denke, man kann mit Sicherheit sagen, dass wir aufgrund einiger Fehler in WebKit Probleme hatten.quelle
arbeite für mich
quelle
else
er ruft den ZustanddecisionHandler
Schließung mit.cancel
so daswebview
eigentlich nicht die ursprüngliche Anforderung laden. Nachdem dasloadRequest
in derelse
Bedingung aufgerufen wurde , wird diese Delegatenmethode für diese Anforderung erneut aufgerufen und geht in dieif
Bedingung über, da derCookie
Header vorhanden ist.else
Zustand versetzt werden.Hier ist meine Version der Mattrs- Lösung in Swift zum Injizieren aller Cookies von HTTPCookieStorage. Dies wurde hauptsächlich durchgeführt, um ein Authentifizierungscookie zum Erstellen einer Benutzersitzung einzufügen.
quelle
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
Cookie setzen
Cookie löschen
quelle
Swift 3 Update:
quelle
HTTPCookieStorage.shared
?Nachdem ich hier verschiedene Antworten durchgesehen hatte und keinen Erfolg hatte, durchsuchte ich die WebKit-Dokumentation und stieß auf die
requestHeaderFields
statische Methode onHTTPCookie
, mit der ein Array von Cookies in ein für ein Headerfeld geeignetes Format konvertiert wird. Die Kombination mit Mattrs Einsicht, dasURLRequest
vor dem Laden mit den Cookie-Headern zu aktualisieren, brachte mich durch die Ziellinie.Swift 4.1, 4.2, 5.0:
Verwenden Sie eine Erweiterung, um dies noch einfacher zu machen:
Jetzt wird es einfach:
Diese Erweiterung ist auch in LionheartExtensions verfügbar, wenn Sie nur eine Drop-In-Lösung wünschen. Prost!
quelle
In iOS 11 können Sie Cookies jetzt verwalten :), siehe diese Sitzung: https://developer.apple.com/videos/play/wwdc2017/220/
quelle
Der Grund für das Posten dieser Antwort ist, dass ich viele Lösungen ausprobiert habe, aber niemand richtig funktioniert. Die meisten Antworten funktionieren nicht, wenn das Cookie zum ersten Mal gesetzt werden muss und das Ergebnis-Cookie beim ersten Mal nicht synchronisiert wird. Verwenden Sie diese Lösung, es funktioniert für beide iOS> = 11.0 <= iOS 11 bis 8.0, funktioniert auch beim ersten Mal mit der Cookie-Synchronisierung.
Für iOS> = 11.0 - Swift 4.2
Holen Sie sich http-Cookies und setzen Sie sie auf diese Weise im wkwebview- Cookie-Store. Es ist sehr schwierig, Ihre Anfrage in wkwebview zu laden , muss Anfrage zum Laden gesendet werden, wenn Cookies vollständig gesetzt werden, hier ist die Funktion, die ich geschrieben habe.
Rufen Sie die Funktion mit Schließung in Vollendung rufen Sie Last Webansicht. Zu Ihrer Information, diese Funktion behandelt nur iOS> = 11.0
Hier ist die Implementierung für die syncCookies- Funktion.
Für iOS 8 bis iOS 11
Sie müssen einige zusätzliche Dinge einrichten, die Sie benötigen, um zwei Zeit-Cookies mithilfe von WKUserScript zu setzen. Vergessen Sie nicht, auf Anfrage auch Cookies hinzuzufügen. Andernfalls wird Ihr Cookie beim ersten Mal nicht synchronisiert und Ihre Seite wird beim ersten Mal nicht richtig geladen. Dies ist der Teufel, den ich gefunden habe, um Cookies für iOS 8.0 zu unterstützen
bevor Sie Wkwebview Objekterstellung.
Konzentrieren Sie sich auf diese Funktion getJSCookiesString
Hier ist ein weiterer Schritt, bei dem wkuserscript Cookies nicht sofort synchronisiert. Es ist sehr schwierig, die erste Seite mit einem Cookie zu laden. Sie müssen die Webansicht erneut laden, wenn der Prozess beendet wird. Ich empfehle jedoch nicht, sie zu verwenden. Dies ist aus Sicht des Benutzers nicht gut Vergessen Sie nicht, die iOS-Versionsprüfung hinzuzufügen, wenn Sie bereit sind, Anforderungssatz-Cookies in den Anforderungsheader zu laden. Rufen Sie vor der Ladeanforderung diese Funktion auf.
Ich habe eine Erweiterung für URLRequest geschrieben
Jetzt können Sie iOS> 8 testen
quelle
Finden Sie sofort die Lösung, die höchstwahrscheinlich für Sie funktioniert. Im Grunde ist es modifiziert und aktualisiert für Swift 4 @ user3589213 ‚s Antwort .
quelle
Ich habe alle oben genannten Antworten ausprobiert, aber keine funktioniert. Nach so vielen Versuchen habe ich endlich einen zuverlässigen Weg gefunden, WKWebview-Cookies zu setzen.
Zuerst müssen Sie eine Instanz von WKProcessPool erstellen und auf die WKWebViewConfiguration setzen, die zum Initialisieren der WkWebview selbst verwendet werden soll:
Das Festlegen von WKProcessPool ist hier der wichtigste Schritt. WKWebview nutzt die Prozessisolation - das heißt, es wird auf einem anderen Prozess ausgeführt als der Prozess Ihrer App. Dies kann manchmal zu Konflikten führen und verhindern, dass Ihr Cookie ordnungsgemäß mit dem WKWebview synchronisiert wird.
Schauen wir uns nun die Definition von WKProcessPool an
Beachten Sie den letzten Satz, wenn Sie dieselbe WKWebview für Teilsequenzanforderungen verwenden möchten
Ich meine, wenn Sie nicht jedes Mal dieselbe Instanz von WKProcessPool verwenden, wenn Sie eine WKWebView für dieselbe Domäne konfigurieren (möglicherweise haben Sie eine VC A, die eine WKWebView enthält, und Sie möchten verschiedene Instanzen von VC A an verschiedenen Stellen erstellen ) kann es zu Konflikten kommen. Um das Problem zu lösen, speichere ich nach der ersten Erstellung des WKProcessPool für eine WKWebView, die Domäne B lädt, diese in einem Singleton und verwende jedes Mal denselben WKProcessPool, wenn ich eine WKWebView erstellen muss, die dieselbe Domäne B lädt
Nach dem Initialisierungsprozess können Sie eine URLRequest in den Abschlussblock von laden
httpCookieStore.setCookie
. Hier müssen Sie das Cookie an den Anforderungsheader anhängen, sonst funktioniert es nicht.P / s: Ich habe die Erweiterung aus der fantastischen Antwort von Dan Loewenherz gestohlen
quelle
Die bessere Lösung für XHR-Anforderungen wird hier gezeigt
Swift 4 Version:
quelle
Wenn jemand Alamofire verwendet, ist dies die bessere Lösung.
quelle
Das funktioniert bei mir: Fügen Sie nach setcookies fetchdatarecords hinzu
quelle
Wenn Sie mehrere Cookie-Elemente hinzufügen, können Sie dies folgendermaßen tun: (
path
&domain
ist für jedes Element erforderlich)Andernfalls wird nur das erste Cookie-Element gesetzt.
quelle
Sie können auch WKWebsiteDataStore verwenden, um ein ähnliches Verhalten wie HTTPCookieStorage von UIWebView zu erhalten.
quelle
Der folgende Code funktioniert gut in meinem Projekt Swift5. Versuchen Sie, die URL von WKWebView unten zu laden:
quelle
Meine Version von Nteiss 'Antwort. Getestet am
iOS 11, 12, 13
. Sieht aus wie Sie müssen nicht verwenden ,DispatchGroup
aufiOS 13
mehr.Ich benutze nicht-statische Funktion
includeCustomCookies
aufWKWebViewConfiguration
, so dass ich aktualisieren kanncookies
jedes Mal , wenn ich neu erstellenWKWebViewConfiguration
.Dann benutze ich es so:
quelle
Dies ist meine Lösung für Cookies und WKWebView in iOS 9 oder höher.
quelle
Dieser Fehler, den ich gemacht habe, ist, dass ich die gesamte URL im Domain-Attribut übergeben habe. Es sollte nur der Domain-Name sein.
quelle