WKWebView从Bundle和Document目录中加载文件

时间:2018-07-26 12:30:46

标签: ios swift wkwebview

我正在使用WKWebView运行一个Webapp,该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方法。

但是,现在我想使用 Document 目录中WKWebView内部的其他资源(在我的情况下为视频),该资源是静态的,可以通过iTunes File Sharing进行管理,同时当然要保持当前状态架构(Bundle目录中的Web资产)。

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

中的HTML5视频

可以这样做吗?

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

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

感谢您的帮助!

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

这有点脏,因为我的所有Web资产现在都可以在我的Document文件夹中看到(但不能修改,因为该文件夹已从Bundle uppon App重新启动中删除并复制了)

1 个答案:

答案 0 :(得分:1)

我最终以编辑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

之类的相对路径访问文档/ 中的文件

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

有点扭曲,但是效果很好。

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