我有一个 HTML 文件,其中包含本地资源文件,例如其内容中的 css、js 和 png 文件。这些本地资源文件为 zip 格式。我的应用程序使用 WKWebView 来显示这个 html 文件。我想找到一种解决方案来拦截 Web 视图请求,以检测哪些本地资源文件与该 html 文件一起加载 -> 如果它们仍然是 zip 格式,则解压缩它们。
我的 HTML 数据内容包含数千个这些本地资源文件,因此我无法在显示内容之前将它们全部解压缩。使用 UIWebView,我们使用 NSURLProtocol 子类来拦截请求,检测本地资源文件并根据用户正在查看的 html 页面按需解压缩。
将 UIWebView 转换为 WKWebView 时遇到此问题。类似的问题在这里发布:https ://forums.developer.apple.com/thread/87474
=======更新=======>
我通过使用WKURLSchemeHandler 弄清楚了。
注意:您需要将文件方案更改为自定义方案才能使用 WKURLSchemeHandler,因为它不适用于文件、http、https 等标准方案。
1.向WKWebView注册自定义scheme
let configuration = WKWebViewConfiguration()
configuration.setURLSchemeHandler(self, forURLScheme: "x-file")
webView = WKWebView(frame: view.bounds, configuration: configuration)
2. 将文件方案转换为自定义方案(x-file),然后用 WKWebView 加载它
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
var htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)
htmlURL = self.changeURLScheme(newScheme: "x-file", forURL: htmlURL)
self.webView.load(URLRequest(url: htmlURL))
3、实现WKURLSchemeHandler协议的2个方法,处理WKURLSchemeTask的3个委托方法。
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
// Your local resource files will be catch here. You can determine it by checking the urlSchemeTask.request.url.
// From here I will unzip local resource files (js, css, png,...) if they are still in zip format
....
// Handle WKURLSchemeTask delegate methods
let url = changeURLScheme(newScheme: "file", forURL: urlSchemeTask.request.url!)
do {
let data = try Data(contentsOf: url)
urlSchemeTask.didReceive(URLResponse(url: urlSchemeTask.request.url!, mimeType: "text/html", expectedContentLength: data.count, textEncodingName: nil))
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
} catch {
print("Unexpected error when get data from URL: \(url)")
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
}