【问题标题】:WKWebView load files from both Bundle and Document directoryWKWebView 从 Bundle 和 Document 目录加载文件
【发布时间】:2019-01-03 10:54:55
【问题描述】:

我正在使用 WKWebView 运行一个 webapp,它从名为 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"))
}

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

但是,现在我想在我的 WKWebView 中使用 Document 目录中的其他资源(在我的情况下为视频),该目录是静态的,可通过 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 符号链接到 Document (奇怪的错误)。 所以我现在决定在每次启动时将 Web_assets 复制到 Document 中,这样我的 Document 文件夹就可以作为 baseURL 与我的视频和网络资产一起使用。

这有点脏,因为我的所有 Web 资源现在都在我的 Document 文件夹中可见(但不可修改,因为该文件夹在 App 重新启动时从 Bundle 中删除和复制)

【问题讨论】:

  • 你应该使用URLRequest并将其加载到你的webview
  • 对不起,我不明白我应该如何使用 URLRequest.. 你能详细说明一下吗?谢谢!
  • 和你做的一样:if let fileURL = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Web_Assets") { webView.load(URLRequest(url: fileURL)) }
  • 好的,这样它就不会设置 baseURL 对吗?那么如何从 insde de webview 访问我的 Document 文件夹?
  • 感谢您的帮助!

标签: ios swift wkwebview


【解决方案1】:

我最终以 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)
    }
    

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

并且我还可以使用 ../video.mp4 等相对路径访问 Documents/ 中的文件

所以 index.html 和 style.css 是通过 Bundle 分发的,在运行时复制到 Documents 中,这样我也可以访问 Documents 文件。

有点扭曲,但效果很好。

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

【讨论】:

  • 是的,恭喜?感谢您扩展我上面的小回复。
猜你喜欢
  • 1970-01-01
  • 2021-01-29
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2015-12-26
  • 1970-01-01
  • 2013-05-25
相关资源
最近更新 更多