ios - WKWebView 从 Bundle 和 Document 目录加载文件

标签 ios swift wkwebview

我正在运行一个使用 WKWebView 的网络应用程序,它从名为 Web_Assets 的 Bundle 目录加载内容和 Assets (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 Assets )。

例如,我的页面 index.html 将从 Web_Assets 加载他的 style.css 和其他 Assets ,并显示位于 Document

中的 HTML5 视频

这有可能吗?

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

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

感谢您的帮助!

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

这有点脏,因为我的所有 Web Assets 现在都在我的文档文件夹中可见(但不可修改,因为该文件夹已被删除并在应用程序重新启动时从 Bundle 复制)

最佳答案

我最终以 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 文件。

有点扭曲,但效果很好。

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

关于ios - WKWebView 从 Bundle 和 Document 目录加载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51538919/

相关文章:

ios - Swift - 移除特定生成的敌人

ios - UIGraphicsGetImageFromCurrentImageContext() 返回 nil

swift -/usr/bin/ld : cannot find -lstdc++ for Ubuntu while trying to "swift build" Perfect2 project

ios - Coreplot plotSymbolWasSelectedAtRecordIndex on touch up

ios - iOS 13 和 Cordova 应用程序不滚动的问题

swift - 抓取加载的网页 URL? WKWebView macOS

ios - 禁用 WKWebView 缩放

ios - 运行 ntimer 来显示广告,但仅显示在某些 View Controller 上

ios - 从正弦扫描计算频率响应的问题

ios - 从 Firebase 中条件读取数据