WKWebView charge les ressources à partir du dossier de document local
dans mon application Swift iOS, je veux télécharger des pages HTML dynamiques à partir d'un serveur distant, les enregistrer dans le répertoire de documents, et afficher ces pages à partir du répertoire de documents.
j'utilisais ceci pour charger la page:
var appWebView:WKWebView?
...
appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath)))
Tout fonctionne sur le simulateur, mais quand je suis passé à de vrais téléphones, il a juste montré une page blanche. Je me suis alors connecté à L'application en utilisant Safari, et j'ai trouvé qu'il se plaignait avec "N'a pas réussi à charger la ressource".
j'ai alors essayé de lire d'abord le contenu de la page à htmlPath
, puis utiliser
appWebView!.loadHTMLString()
pour charger la page. Cela fonctionne quand la page HTML est simple. Mais si le HTML renvoie à autre chose, c'est-à-dire à un fichier JavaScript également dans le répertoire des documents (avec un chemin absolu comme <script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">
), il ne se chargera pas.
est-ce que quelqu'un sait pourquoi cela se produit, et comment résoudre le problème?
plus d'informations:
- version XCode: 7.3.1 Cible de déploiement
- : 8.1 (j'ai essayé d'utiliser 9.3 aussi, mais cela n'a pas aidé.)
4 réponses
c'est une version simplifiée de ce que j'ai utilisé pour charger des fichiers locaux dans un de mes projets (iOS 10, Swift 3). Je viens mis à jour mon code (7.5.2017) après l'avoir testé à nouveau sur iOS 10.3.1 et iPhone 7+ comme demandé par Raghuram et Fox5150 dans les commentaires.
je viens de créer un tout nouveau projet et voici la structure du dossier:
Mise à jour le 19.04.2018: a ajouté une nouvelle fonctionnalité pour télécharger A.zip avec les fichiers HTML, CSS, JS, décompressez le dans /Documents/ (Alamofire + Zip) puis chargez ces fichiers dans le webView. Vous pouvez le trouver dans la GitHub exemple de projet . De nouveau, n'hésitez pas à fourche et l'étoile! :)
mise à jour 08.02.2018: a finalement ajouté un GitHub sample project , qui comprend également un fichier JavaScript local. Hésitez pas à la fourche et l'étoile! :)
Version 1 avec webView.loadFileURL ()
ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let htmlUrl = URL(fileURLWithPath: htmlPath!, isDirectory: false)
webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl)
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Version 2 avec webView.loadHTMLString ()
ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let folderPath = Bundle.main.bundlePath
let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
do {
let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
} catch {
// catch error
}
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Pièges à regarder dehors pour:
- assurez-vous que vos fichiers html/js/css locaux sont dans le projet - > objectif -> phases de construction - > paquet de copie Ressources
- assurez-vous que vos fichiers html ne font pas référence à des chemins relatifs par exemple
css/styles.css
parce que iOS aplatira la structure et les styles de vos fichiers.css sera au même niveau que l'indice.html écrire<link rel="stylesheet" type="text/css" href="styles.css">
à la place
étant donné les 2 versions et les gotchas voici mes fichiers html/css du projet:
web / index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Offline WebKit</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1 id="webkit-h1">Offline WebKit!</h1>
</body>
</html>
web/css / styles.css
#webkit-h1 {
font-size: 80px;
color: lightblue;
}
si quelqu'un veut un projet d'échantillon GitHub, dites-le moi dans la section des commentaires et je le téléchargerai.
Méthode Swift 4
cette méthode permet à WKWebView de lire correctement votre hiérarchie de répertoires et de sous-répertoires pour les fichiers CSS/JS liés. Vous faites pas besoin de changer votre code HTML, CSS ou JS.
mise à jour pour Xcode 9.3
Étape 1
importer le dossier des fichiers Web locaux n'importe où dans votre projet. Assurez-vous que vous:
envoyer les éléments de copie si nécessaire
☑️ Créer un dossier de références (pas de "Créer des groupes")
ajouter aux objectifs
l'Étape 2
aller au contrôleur de vue avec le WKWebView et ajouter le code suivant à la viewDidLoad
méthode:
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
-
index
– le nom du fichier à charger (sans l'extension.html
) -
website
- le nom de votre dossier web (index.html
devrait être à la racine de ce répertoire)
Conclusion
le code général devrait ressembler à quelque chose comme ceci:
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
webView.navigationDelegate = self
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
}
}
si l'un d'entre vous a d'autres si vous avez des questions sur cette méthode ou sur le code, je ferai de mon mieux pour y répondre. :)
Cette solution m'a aidé:
[configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
cela fonctionne bien (Swift 3, Xcode 8):
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
if let url = Bundle.main.url(forResource: "file", withExtension: "txt")
{
do
{
let contents = try String(contentsOfFile: url.path)
webView.loadHTMLString(contents, baseURL: url.deletingLastPathComponent())
}
catch
{
print("Could not load the HTML string.")
}
}
}
}