简体   繁体   English

iOS:WKWebview 如何允许位于 bundle 中的 html 文件对文档目录的读取权限

[英]iOS: WKWebview how to allow html file located in bundle read access to documents directory

I have an html file located in a bundle and I'm using WKWebView to load content from this html:我有一个位于捆绑包中的 html 文件,我正在使用 WKWebView 加载来自此 html 的内容:

let fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"demo", ofType: "html")!)
    webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)

However, this html file have some scripts which are trying to get access to files located in Documents dir (some videos saved in there) but get a "can't load local resources."然而,这个 html 文件有一些脚本试图访问位于 Documents 目录中的文件(一些视频保存在那里)但得到“无法加载本地资源”。 error.错误。 I'm using this files somewhere else in AVPlayerViewController so I know the files exists and the url I'm using is the right one.我在 AVPlayerViewController 的其他地方使用这些文件,所以我知道这些文件存在,并且我使用的 url 是正确的。

I tried:我试过了:

1. pass the documents dir url to the allowingReadAccessTo parameter - the webview doesn't even load 1.将文档目录 url 传递给 allowedReadAccessTo 参数 - webview 甚至不加载

2. Copy the items from documents dir to tmp dir and passing this (tmp dir) url in the scripts - it works , but this process happens too much and I don't want to copy so many files due to memory issues and the time it take for big files. 2.将文件目录中的项目复制到 tmp 目录并在脚本中传递这个 (tmp dir) url -它可以工作,但是这个过程发生的太多了,由于 memory 问题和时间,我不想复制这么多文件它需要大文件。

3. Copy the html file and its scripts from the bundle to documents dir - not relevant because the scripts Im using changes from time to time, so to make sure the user always have the last version (of the scripts) I will have to copy it every time the app launches. 3.将 html 文件及其脚本从捆绑包复制到文档目录 -不相关,因为我使用的脚本不时更改,因此为了确保用户始终拥有(脚本的)最新版本,我将不得不复制每次应用程序启动时。

So, is there any other way to allow html file (located in bundle) access the documents file?那么,有没有其他方法可以让 html 文件(位于捆绑包中)访问文档文件?

Thanks in advance,提前致谢,

This covers one file, but you should be able to build a function that copies the relevant files to the Documents Directory using the code below.这涵盖了一个文件,但您应该能够构建一个函数,使用以下代码将相关文件复制到文档目录。

///Copy the file from the bundle to the Documents Directory
guard let bundleURL = Bundle.main.url(forResource:"demo", ofType: "html") else {
     preconditionFailure("Unable to get bundle URL") 
}

guard let documentsDirectory = let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
     preconditionFailure("Unable to get Documents URL") 
}

let newURL = documentsDirectory.appendingPathComponent("demo.html")

do {
   try FileManager.default.copyItem(at: bundleURL, to: newUrl)
} catch {
   print("Error copying bundle: \(error)")
}


///Setup the WKWebView
let prefs = WKPreferences()
prefs.javaScriptEnabled = true

let webConfig = WKWebViewConfiguration()
webConfig.preferences = prefs

var webViewer = WKWebView(frame: view.frame, configuration: webConfig)
webViewer.loadFileURL(newURL, allowingReadAccessTo: documentsDirectory)

Keep in mind, the Bundle is located in a different directory altogether within your app.请记住,Bundle 在您的应用程序中完全位于不同的目录中。 Just because the file has access to the Documents Directory does not mean that the HTML within the file will be able to find the referencing scripts or other HTML files you're referencing.仅仅因为文件可以访问文档目录并不意味着文件中的 HTML 将能够找到您正在引用的引用脚本或其他 HTML 文件。 You should consider everything within the bundle to be immutable and the location itself a source origin only.您应该将捆绑包中的所有内容视为不可变的,并且位置本身仅是源来源。

This is a little old now but in case anyone else is having this issue, I was having the exact same problem after finally updating from UIWebView to WKWebView .这现在有点老了,但万一其他人遇到这个问题,我最终从UIWebView更新到WKWebView后遇到了完全相同的问题。 It seems to be related to the new security enhancements of WKWebView .这似乎与WKWebView的新安全增强有关。 Oddly enough, I was only experiencing issues on my real device and not on the simulator.奇怪的是,我只是在我的真实设备上遇到问题,而不是在模拟器上。

Basically, I had an html template file in the main app bundle, and then in my code I would load the html file in a WKWebView (after my code replaced some placeholders with URLs to user-created images stored in FileManager.documentDirectory() . The html file would load in the WKWebView , but the images were blank white squares.基本上,我在主应用程序包中有一个 html 模板文件,然后在我的代码中,我将在 WKWebView 中加载 html 文件(在我的代码将一些占位符替换为存储在FileManager.documentDirectory()中的用户创建图像的 URL 之后。 html 文件将加载到WKWebView中,但图像是空白的白色方块。

Using loadFileURL(_:allowingReadAccessTo:) seems to allow the HTML file to access the user images stored in documentDirectory :使用loadFileURL(_:allowingReadAccessTo:)似乎允许 HTML 文件访问存储在documentDirectory中的用户图像:

  if let docDirectory = FileManager.documentDirectory() {
    do {
      let bundleHtmlTemplateURL = URL(fileURLWithPath: bundleHtmlTemplatePath)
      // I'm guessing the below line resolves the supposed security / access issue
      self.webView.loadFileURL(bundleHtmlTemplateURL, allowingReadAccessTo: docDirectory)
    
      self.webView.loadHTMLString(htmlContents, baseURL: docDirectory)
      
      let contents = try FileManager.default.contentsOfDirectory(at: docDirectory, includingPropertiesForKeys: nil, options: [])
      // do other stuff
    } catch {
      print("error loading pdf preview")
  }
}

Hope that helps!希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM