WKWebView从Bundle和Document目录加载文件

mai*_*gre 6 ios swift wkwebview

我正在使用 WKWebView 运行一个 web 应用程序,它从名为Web_Assets 的Bundle 目录加载内容和资产(html、js、img、css ...)。

我像这样加载index.html,并将Web_assets设置为baseURL:

if let filePath = Bundle.main.path(forResource:"index", ofType:"html", inDirectory: "Web_Assets") { 
    let html = try String(contentsOfFile: filePath, encoding: .utf8)
    webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL?.appendingPathComponent("Web_Assets"))
}
Run Code Online (Sandbox Code Playgroud)

这工作得很好:index.html 已加载,并且 Web_Assets 用作其他资源的基本路径,没有任何问题。我还可以使用等效的 loadFileURL 方法(根据我的理解)。

但是,现在我想使用Document目录中的 WKWebView 中的其他资源(在我的例子中是视频),该目录是静态的并且可以通过 iTunes 文件共享进行管理,同时当然保持当前的架构不变(Bundle 目录中的 Web 资源) )。

例如,我的页面index.html将从Web_Assets加载他的style.css和其他资源,并显示位于Document中的HTML5视频

是否有可能做到这一点 ?

想法(我不知道如何实现):

  1. Web_assets 中文档的符号链接?
  2. WKWebView 中不同文件类型的 baseURL 不同?(将所有请求路由到 Web_Assets,除了路由到 Document 的 mp4 文件请求)

感谢您的帮助 !

编辑 1: 想法 1 是不可能的,因为 Bundle 目录是只读的。文档无法在 Web_assets 中进行符号链接。我也无法将 Web_assets 符号链接到文档中(奇怪的错误)。因此,我现在决定在每次启动时将 Web_assets 复制到 Document 内,这样我的 Document 文件夹就可以作为我的视频和 Web 资源的基本 URL。

这有点脏,因为我的所有网络资源现在都在我的文档文件夹中可见(但不可修改,因为应用程序重新启动后该文件夹会被删除并从捆绑包中复制)

mai*_*gre 4

我最终得到了 EDIT 1 和 @ngbaanh 的建议:

  • 在 viewDidLoad 上:

    let filemgr = FileManager.default
    docURL = filemgr.urls(for: .documentDirectory, in: .userDomainMask)[0]
    destPath = docURL.path+"/www/"
    sourcePath = Bundle.main.resourceURL!.appendingPathComponent("Web_Assets").path
    
    //COPY Web_Assets content from Bundle to Documents/www
    do {
        try filemgr.removeItem(atPath: destPath)
    } catch {
        print("Error: \(error.localizedDescription)")
    }
    do {
        try filemgr.copyItem(atPath: sourcePath, toPath: destPath)
    } catch {
        print("Error: \(error.localizedDescription)")
    }
    
    // Configure Webview
    webView.navigationDelegate = self
    webView.configuration.userContentController.add(self, name: "teleco")
    do {
       let baseURL = try filemgr.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
       let fileURL = baseURL.appendingPathComponent("www/index.html")
       self.loadFileURL(fileURL, allowingReadAccessTo: baseURL)
    } catch {
       print(error)
    }
    
    Run Code Online (Sandbox Code Playgroud)

这样我的baseURL是Documents/www/ 所以在我的index.html中我可以包含像style.css这样的资源

我还可以使用相对路径(如../video.mp4 )访问Documents/中的文件

因此,index.html 和 style.css 通过 Bundle 分发,在运行时复制到 Documents,这也允许我访问 Documents 文件。

有点扭曲,但效果很好。

缺点:它在用户可访问的 Documents 文件夹中公开 Web_assets 文件。但它们无法更改,因为它们在应用程序启动时被替换。