I'm attempting to parse out some HTML metadata from a third-party URL; however, I don't get the full HTML data until some Javascript scripts are executed in the WKWebView.
So I've been trying to detect when the WKWebView has completely loaded the web page with Javascript but unfortunately I wasn't able to.
Here's what I tried:
- I tried using
WKUserContentControllerand handled the protocol method but that didn't work because the protocol method is only executed when it receives a script message not when it's completed. - I tried adding an observer for
WKWebView'sestimatedProgressbutestimatedProgressreturn 1.0 before JS scripts are done loading. - I tried using
WKNavigationDelegateprotocol methodwebView(_ webView: WKWebView, didFinish navigation: WKNavigation!)but it's essentially the same thing as adding an observer. - I also tried using
WKWebView'sevaluateJavaScriptmethod in theobserveValuemethod to check both:document.readyState == \"interactive\"document.readyState == \"completed\"
but that didn't work either because it's executed way before JS is done loading.
Code
Here's the code of the last approach I attempted and didn't work:
Initializing the WKWebView
let webView = WKWebView(frame: self.view.frame)
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
webView.load(URLRequest(url: url))
webView.navigationDelegate = self
self.view.addSubview(webView)
Handling the observer
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "estimatedProgress" {
if let webView = object as? WKWebView, webView.estimatedProgress > 0.5 {
print(webView.estimatedProgress)
webView.evaluateJavaScript("document.readyState == \"interactive\"") { (isLoaded, err) in
print(isLoaded)
if let loaded = isLoaded as? Bool, loaded == true {
print("completely done loading with JS")
}
}
}
}
}
The result I get when the evaluateJavaScript method is executed is false because it's executed too early. But I'm trying to let the observer continue until isLoaded is true.