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.") } } } }