Swift-iOS-Cache WKWebView Inhalte für die offline-Ansicht
Versuchen wir speichern die Inhalte (HTML) von WKWebView in einem persistenten Speicher (NSUserDefaults, CoreData-oder disk-Datei). Kann der Benutzer sehen den gleichen Inhalt, wenn er wieder in die Anwendung ohne internet-Verbindung. WKWebView nicht NSURLProtocol wie UIWebView (siehe post hier).
Obwohl ich gesehen haben, Beiträge, die "offline application cache ist nicht aktiviert in WKWebView." (Apple dev-Foren), weiß ich, dass eine Lösung existiert.
Ich gelernt habe, zwei Möglichkeiten, aber ich konnte nicht machen Sie zu arbeiten:
1) Wenn ich öffnen Sie eine website in Safari für Mac und wählen Sie Datei >> "Speichern unter" erscheint die folgende option im Bild unten. Für Mac-apps vorhanden [[[webView mainFrame] dataSource] webArchive], aber auf UIWebView oder WKWebView es gibt keine solche API. Aber wenn ich es laden ein .webarchive-Datei in Xcode auf WKWebView (wie die, die ich erhielt von Mac-Safari), dann wird der Inhalt richtig angezeigt (html-externe Bilder, video-Vorschau), wenn es keine internet-Verbindung. Die .webarchive-Datei ist eigentlich eine plist (property list). Ich habe versucht, ein mac-framework erstellt wird .webarchive-Datei, aber es war unvollständig.
2) ich obtanined den HTML-Code in webView:didFinishNavigation aber es speichert keine externen Bilder, css, javascript
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
webView.evaluateJavaScript("document.documentElement.outerHTML.toString()",
completionHandler: { (html: AnyObject?, error: NSError?) in
print(html)
})
}
Wir kämpfen, über eine Woche und es ist ein wesentliches Merkmal für uns.
Jede Idee wirklich dankbar.
Danke!
- Hallo Cristi..hast du es geschafft, den cache der HTML-Code für die offline-Anzeige in WKWebview?
- Aktualisierungen auf dieser? Ich bin versucht, dieses problem zu lösen
- Ich weiß, das ist Monate zu spät, aber was können Sie tun, ist die JS und die CSS in der HTML-Datei selbst (vorausgesetzt, Sie Steuern die Seiten, die Sie besuchen in der webview). dann
outerHTML.toString()
zurück Sie alle. Nachteil hier ist die Leistung laden von HTML, die ich gefunden habe, langsam zu sein. in der Hoffnung auf Verbesserung der Geschwindigkeit auf mein Ende .webarchive Lösung - keine news auf, die Frage ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß, ich bin spät, aber ich habe in letzter Zeit auf der Suche nach einer Möglichkeit zum speichern von Webseiten zum offline-Lesen, und konnte immer noch keine zuverlässige Lösung, würde nicht hängen auf der Seite selbst und nicht veraltet
UIWebView
. Viele Leute schreiben, man solle die vorhandene HTTP-caching, aber WebKit zu tun scheint, eine Menge Sachen, die out-of-process, so dass es praktisch unmöglich durchzusetzen komplette caching (siehe hier oder hier). Aber diese Frage führte mich in die richtige Richtung. Basteln mit dem web-Archiv Ansatz, fand ich, dass es eigentlich ganz einfach zu schreiben Sie Ihre eigenen web-Archiv Exporteur.Wie geschrieben die Frage, die web-Archive, nur der plist-Dateien, also alles was es braucht ist ein crawler, der extrahiert die erforderlichen Ressourcen aus der HTML-Seite, downloads und speichert diese in einer großen plist-Datei. Diese Archiv-Datei kann dann später geladen werden, in der
WKWebView
überloadFileURL(URL:allowingReadAccessTo:)
.Erstellte ich eine demo-app, ermöglicht das archivieren von und die Wiederherstellung bis zu einem
WKWebView
mit diesem Ansatz: https://github.com/ernesto-elsaesser/OfflineWebViewDie Umsetzung hängt nur von Fuzi für das HTML-parsing.
Ich würde empfehlen, untersucht die Machbarkeit der Verwendung von App-Cache, die jetzt unterstützt
WKWebView
ab iOS 10: https://stackoverflow.com/a/44333359/233602Ich bin mir nicht sicher, ob Sie wollen einfach nur zum Zwischenspeichern von Seiten, die bereits besucht wurden oder wenn Sie spezifische Anfragen, die Sie möchten, um zu cache. Ich bin derzeit auf letztere. Also werde ich darüber sprechen. Meine urls dynamisch generiert werden, von einer api-Anfrage. Von dieser Antwort, die ich eingestellt
requestPaths
mit dem nicht-Bild-urls und dann einen Antrag stellen für jede der urls und die Antwort Zwischenspeichern. Für die Bild-urls, benutzte ich die Eisvogel Bibliothek zum Zwischenspeichern der Bilder. Ich habe bereits meine shared cacheurlCache = URLCache.shared
in meiner AppDelegate. Und teilte die Speicher, die ich brauche:urlCache = URLCache(memoryCapacity: <setForYourNeeds>, diskCapacity: <setForYourNeeds>, diskPath: "urlCache")
Dann rufen SiestartRequest(:_)
für jede der urls inrequestPaths
. (Kann getan werden, in den hintergrund, wenn es nicht notwendig sofort)Ich bin mit Alamofire für die Netzwerk-Anfrage mit einer cachingSessionManager konfiguriert mit den entsprechenden Headern. Also in meinem WebService-Klasse die ich habe:
Dann in der Webansicht delegate-Methode lade ich die cachedResponse. Ich verwende eine variable
handlingCacheRequest
um eine Endlosschleife zu vermeiden.Natürlich werden Sie damit umgehen wollen, wenn es ein Fehler als gut.
Ich hoffe, das hilft. Die einzige Sache, die ich bin immer noch versuchen, herauszufinden, ist die Bild-assets nicht geladen werden offline. Ich denke, ich werde brauchen, um eine separate Anforderung für diese Bilder und halten Sie einen Verweis zu Ihnen vor Ort. Nur so ein Gedanke aber ich werde diese zu aktualisieren, wenn ich das habe, geklappt.
AKTUALISIERT mit Bildern laden von offline-mit dem code unten
Ich benutzte die Kanna Bibliothek zum Parsen meine html-string aus meiner zwischengespeicherte Antwort, finde die url eingebettet in der
style= background-image:
- Attribut des div, regex verwendet, um die url (das ist auch der Schlüssel für die Kingfisher-Cache Bild), holte das zwischengespeicherte Bild, und dann verändert die css, um die Bild-Daten (basierend auf diesem Artikel: https://css-tricks.com/data-uris/) geladen und dann die webview mit dem geänderten html-Code. (Puh!) Es war ganz der Prozess und vielleicht gibt es einen einfacheren Weg.. aber ich hatte es nicht gefunden. Mein code aktualisiert, um alle diese änderungen. Viel Glück!Einfachste Weg, cache-Webseite ist wie folgt in Swift 4.0: -
/* Wo isCacheLoad = true (Offline-Daten laden) &
isCacheLoad = false (Normal-laden von Daten) */