【问题标题】:Loading local file works fine in simulator but crash on device加载本地文件在模拟器中工作正常,但在设备上崩溃
【发布时间】:2016-03-07 15:25:20
【问题描述】:

使用 WKWebview 播放本地文件可在模拟器上运行,但在设备上出现此错误 (iOS 9.2.1)

fail in didFailProvisionalNavigation Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"
UserInfo={NSErrorFailingURLKey=file:///var/mobile/Containers/Data/Application/2FBE4DE6-9441-4C5A-BB1F-8598CA89664C/Documents/courses/agdg_test1455704820291/index.html?jqueryFilePath=file:///var/mobile/Containers/Bundle/Application/5A442D34-3360-46C7-8B28-B6F3AED373CE/elearning.app/view/jquery.js&commandsFilePath=file:///var/mobile/Containers/Bundle/Application/5A442D34-3360-46C7-8B28-B6F3AED373CE/elearning.app/view/commands.js,
_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x15e295f0>,NSErrorFailingURLStringKey=file:///var/mobile/Containers/Data/Application/2FBE4DE6-9441-4C5A-BB1F-8598CA89664C/Documents/courses/agdg_test1455704820291/index.html?jqueryFilePath=file:///var/mobile/Containers/Bundle/Application/5A442D34-3360-46C7-8B28-B6F3AED373CE/elearning.app/view/jquery.js&commandsFilePath=file:///var/mobile/Containers/Bundle/Application/5A442D34-3360-46C7-8B28-B6F3AED373CE/elearning.app/view/commands.js}

这是配置 webView 的代码:

let lesson:NSMutableArray = courseDB_Manager.getInstance().getRowDB("SELECT * FROM lesson_chapter WHERE lesson_chapter_id = ?", args: [chapterToPlay], structType: "lesson_chapter")
let occ: lesson_chapter_struct = lesson[0] as! lesson_chapter_struct
fileToPlay = Utility.getPath("courses/" + occ.lesson_chapter_fichier)

let commandsFilePath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("commands", ofType: "js", inDirectory: "view")!, isDirectory: false)
let jqueryFilePath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("jquery", ofType: "js", inDirectory: "view")!, isDirectory: false)

let target = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("start", ofType: "html", inDirectory: "view")!, isDirectory: false)
let params = "?fileToPlay=" + fileToPlay + "&commandsFilePath=" + String(commandsFilePath) + "&jqueryFilePath=" + String(jqueryFilePath) + "&" + NSUUID().UUIDString
let url = NSURL(string: NSString(string: target.absoluteString + params) as String)
NSURLCache.sharedURLCache().removeAllCachedResponses()
NSURLCache.sharedURLCache().diskCapacity = 0

if(progress.current() != 1) {
    let askForResume = UIAlertController(title: "Resume", message: "Resume ????????????", preferredStyle: UIAlertControllerStyle.Alert)
    askForResume.addAction(UIAlertAction(title: "YES", style: .Default, handler: { (action: UIAlertAction!) in
        self.resume = true
        self.webView.loadFileURL(url!, allowingReadAccessToURL: url!)
    }))
    askForResume.addAction(UIAlertAction(title: "NO", style: .Default, handler: { (action: UIAlertAction!) in
        self.webView.loadFileURL(url!, allowingReadAccessToURL: url!)
    }))
    presentViewController(askForResume, animated: true, completion: nil)
} else {
    self.webView.loadFileURL(url!, allowingReadAccessToURL: url!)
}

在执行allowingReadAccessToURL 后,我遇到了这个错误:

Received an unexpected URL from the web process: 'file:///[...]commands.js'
Received an invalid message "WebPageProxy.DecidePolicyForNavigationAction" from the web process.

是因为js请求的文件遇到了同样的问题?

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    decisionHandler(WKNavigationActionPolicy.Allow)
}

更新 1 - 在第二次更新中解决

现在,我正在使用此代码:

let target = NSURL(fileURLWithPath: fileToPlay + "/index.html", isDirectory: false)
let params = "?commandsFilePath=" + String(commandsFilePath) + "&jqueryFilePath=" + String(jqueryFilePath) + "&" + NSUUID().UUIDString
let url = NSURL(string: NSString(string: target.absoluteString + params) as String)

if #available(iOS 9.0, *) {
    self.webView.loadFileURL(url!, allowingReadAccessToURL: url!)
} else {
    do {
        let fileUrl = try self.fileURLForBuggyWKWebView8(url!)
        self.webView.loadRequest(NSURLRequest(URL: fileUrl))
    } catch let error as NSError {
        print("Error: " + error.debugDescription)
    }
}

在模拟器(iOS 9)上运行良好,即加载fileUrl和js代码包含的文件。 但是在设备上(也是 iOS 9),它加载了 fileUrl 和 mainBundle 中包含的 js 文件,但不加载 fileUrl 同一目录中的 js 文件

例如: fileUrl 指向

“file:///var/mobile/Containers/Data/Application/4F2A96AF-8E58-41A6-A4D3-A19D254C048F/Documents/courses/agdg_test1455704820291/index.html”

包含 fileUrl 子目录中的 js 文件不起作用

“file:///var/mobile/Containers/Data/Application/4F2A96AF-8E58-41A6-A4D3-A19D254C048F/Documents/courses/agdg_test1455704820291/data/player.js”

但是完美地包含来自捆绑工作的 js 文件。我还使用 iPad 文件资源管理器验证了文件 /data/player.js 存在并且确实如此。

更新 2

我通过将allowingReadAccessToURL 设置为整个目录解决了这个问题,而不仅仅是我的索引文件。

因为我使用这种方法来配置 WKWebView,所以 js 代码永远不会完成缓冲声音/视频以在设备上播放...我不明白在 -[WKWebView loadFileURL:allowingReadAccessToURL:][WKWebView loadRequest] 之间执行如此缓慢的区别是谁

【问题讨论】:

  • 这个“本地文件”在哪里?您是把它作为资源添加到您的项目中,还是在您的计算机上?
  • 不是,是app里面的app文档下载的。应用程序与设备上的 UIWebView 一起工作正常(但执行我的 js 播放器的速度很慢),文件完全相同,但只能在带有 WKWebView 的模拟器中工作。我编辑我的问题以给出所有返回的错误。
  • 请添加您如何加载数据的代码。还有,iOS 9?在 iOS 8 中,您无法从 WKWebView 中的文件 URL 加载。
  • 看看我的回答。您不能在 WKWebView 中以这种方式加载本地文件。

标签: ios uiwebview


【解决方案1】:

在 iOS 9 及更高版本中,WKWebView 有一个新方法可以满足您的需求,-[WKWebView loadFileURL:allowingReadAccessToURL:]

确保您正在使用该调用加载本地资源。

如果您支持 iOS 8,那就有点困难了。有关详细信息,请参阅this answer

【讨论】:

  • 仅供参考,iOS 8 支持导致我不得不在我们的应用程序中使用 UIWebview。 WKWebView 的好处并不能证明变通办法的工作/风险。
  • 我在 js 中使用我们的播放器开发了离线电子学习,在 Android 和 UWP webview 上工作正常,但在 UIWebView(缓冲缓冲)上运行时间过长,因此 WKWebView 似乎在模拟器上运行良好。我编辑我的问题以添加新问题
  • 您的代码正在使用[WKWebView loadRequest:]。您是否尝试过我在回答中提到的 loadFileURL?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 2015-12-06
  • 2013-10-08
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
相关资源
最近更新 更多