web-dev-qa-db-fra.com

Charger des fichiers et des ressources Web locaux dans WKWebView

Contrairement à UIWebView et aux versions précédentes de WKWebView (iOS 10 & macOS 10.12), l’opération de chargement par défaut pour les fichiers locaux a été déplacée de Bundle.main.path à Bundle.main.url. De même, loadFileURL est également devenu la fonction par défaut pour charger des ressources locales dans WKWebView.

Je le sais .path et .url sont complètement différents et ont tous deux travaillé dans le passé - .path étant historiquement la méthode choisie par défaut; cependant, il semble que les dernières versions de Swift ont cassé la plupart, sinon la totalité, .path solutions. Le .path _ solutions semblent maintenant aplatir la hiérarchie des répertoires, en plaçant tout le contenu CSS, JS et tout autre sous-répertoire dans un seul et même grand répertoire. Cela provoque des erreurs de chargement lorsque WKWebView tente de charger index.html, par exemple avec une feuille de style liée à un sous-dossier (c'est-à-dire. /css/style.css).

Après avoir lu de nombreuses questions et trouvé d'innombrables réponses incertaines/erronées, existe-t-il une solution rapide et sans problème pour mettre en œuvre un WKWebView capable de charger des ressources locales (y compris des fichiers CSS/JS liés), sans solution de rechange?

14
Matt Swift

mis à jour pour Swift 4, Xcode 9.3


Cette méthode permet à WKWebView de lire correctement votre hiérarchie de répertoires et de sous-répertoires pour les fichiers CSS, JS et la plupart des fichiers liés. Vous n'avez [~ # ~] pas [~ # ~] besoin de changer votre code HTML, CSS ou JS.

Solution (rapide)

  1. Ajoutez le dossier Web à votre projet (Fichier> Ajouter des fichiers au projet)
    • Copier les éléments si nécessaire
    • Créer des références de dossiers *
    • Ajouter aux cibles (qui sont applicables)
  2. Ajoutez le code suivant au viewDidLoad et personnalisez-le selon vos besoins:

    let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
    webView.loadFileURL(url, allowingReadAccessTo: url)
    let request = URLRequest(url: url)
    webView.load(request)
    

Solution (en profondeur)

Étape 1

Importez le dossier des fichiers Web locaux n’importe où dans votre projet. Assurez-vous que vous:

Xcode > File > Add Files to "Project"

☑️ Copier les éléments si nécessaire

☑️ Créer des références de dossier (pas "Créer des groupes")

☑️ Ajouter aux cibles

Étape 2

Accédez au contrôleur de vue avec WKWebView et ajoutez le code suivant à la méthode viewDidLoad:

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 le .html _ extension)
  • 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 à 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 vous avez des questions à propos de cette méthode ou du code, je ferai de mon mieux pour y répondre!

43
Matt Swift

Ce travail pour moi:

        WKWebView *wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
        wkwebView.navigationDelegate = self;
        wkwebView.UIDelegate = self;
        [wkwebView.configuration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
        NSURL *url = [NSURL fileURLWithPath:YOURFILEPATH];
        [wkwebView loadFileURL:url allowingReadAccessToURL:url.URLByDeletingLastPathComponent];
        [self.view addSubview:wkwebView];
2
Zouhair Sassi