WKWebView从本地文档文件夹加载资源

在我的swift iOS应用程序中,我想从远程服务器下载一些dynamichtml页面,保存在文档目录中,并从文档目录中显示这些页面。

我正在使用它来加载页面

var appWebView:WKWebView? ... appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath))) 

一切工作在模拟器上,但是当我转移到真正的手机,它只是显示一个空白页面。 然后,我使用Safari浏览器连接到应用程序,发现它抱怨“无法加载资源”。

然后我试着先在htmlPath读取页面的内容,然后使用

 appWebView!.loadHTMLString() 

加载页面。 它在html页面很简单的时候工作。 但是如果html引用别的东西,也就是一个javascript也在文档目录下(带有一个像<script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js"> ),将无法加载。

任何人都知道为什么发生这种情况,如何解决这个问题

更多信息:

  • XCode版本:7.3.1
  • 部署目标:8.1(我也尝试使用9.3,没有帮助)

这是我用来加载我的项目(iOS 10,Swift 3)中的本地文件的简化版本。 我刚刚更新了我的代码(7.5.2017),在Raghuram和Fox5150的要求下,在iOS 10.3.1和iPhone 7+上再次进行了testing。

我刚刚创build了一个全新的项目,这是文件夹结构: 在这里输入图像说明

版本1与webView.loadFileURL()

ViewController.swift

 import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { override func viewDidLoad() { super.viewDidLoad() let webView = WKWebView() let htmlPath = Bundle.main.path(forResource: "index", ofType: "html") let htmlUrl = URL(fileURLWithPath: htmlPath!, isDirectory: false) webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl) webView.navigationDelegate = self view = webView } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } 

版本2与webView.loadHTMLString()

ViewController.swift

 import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { override func viewDidLoad() { super.viewDidLoad() let webView = WKWebView() let htmlPath = Bundle.main.path(forResource: "index", ofType: "html") let folderPath = Bundle.main.bundlePath let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true) do { let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue) webView.loadHTMLString(htmlString as String, baseURL: baseUrl) } catch { // catch error } webView.navigationDelegate = self view = webView } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } 

需要注意的是:

  • 确保你的本地html / js / css文件在Project – > Target – > Build Phases – > Copy Bundle Resources
  • 确保你的html文件没有引用相对path,例如css/styles.css因为iOS会压扁你的文件结构,styles.css将和index.html在同一层,所以写<link rel="stylesheet" type="text/css" href="styles.css">代替

鉴于这两个版本和gotcha的这里是我的项目的HTML / CSS文件:

networking/ index.html的

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Offline WebKit</title> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <h1 id="webkit-h1">Offline WebKit!</h1> </body> </html> 

networking/ CSS / Styles.css中

 #webkit-h1 { font-size: 80px; color: lightblue; } 

如果有人想要一个GitHub示例项目,请在评论部分告诉我,我会上传它。

这个解决scheme帮助我:

 [configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"]; 

这工作得很好(Swift 3,Xcode 8):

 import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func loadView() { webView = WKWebView() webView.navigationDelegate = self view = webView } override func viewDidLoad() { super.viewDidLoad() if let url = Bundle.main.url(forResource: "file", withExtension: "txt") { do { let contents = try String(contentsOfFile: url.path) webView.loadHTMLString(contents, baseURL: url.deletingLastPathComponent()) } catch { print("Could not load the HTML string.") } } } }