How to intercept a WKWebView request to detect which local resource files (css, js, png, …) load together with a HTML file?

二次信任 提交于 2020-02-22 04:17:12

问题


I have a HTML file which contains local resource files such as css, js and png files inside its content. These local resource files are in zip format. My app use WKWebView to display this html file. I want to find a solution to intercept the web view request to detect which local resource files are load together with this html file -> then unzip them if they are still zip format.

My HTML data content contains thousands of these local resource file so I can't unzip all of them before display content. With UIWebView, we are using NSURLProtocol subclass to intercept the request, detect local resource files and un-zip it on demand based on the html page which user is viewing.

I am having this issue when convert UIWebView to WKWebView. Similar problem was post here: https://forums.developer.apple.com/thread/87474

======= Update =======>

I figured it out by using WKURLSchemeHandler.

Note: You need to change the file scheme to a custom scheme in order to use WKURLSchemeHandler because it will not work with standard schemes like file, http, https.

1. Register custom scheme with WKWebView

    let configuration = WKWebViewConfiguration()
    configuration.setURLSchemeHandler(self, forURLScheme: "x-file")
    webView = WKWebView(frame: view.bounds, configuration: configuration)

2. Convert file scheme to the custom scheme (x-file) then load it with 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. Implement 2 methods of WKURLSchemeHandler protocol and handle 3 delegate methods of WKURLSchemeTask.

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

来源:https://stackoverflow.com/questions/58385398/how-to-intercept-a-wkwebview-request-to-detect-which-local-resource-files-css

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!