I have a Coordinator running evaluateJavascript on WkWebView didFinish
.
The evaluate is getting the document.body.scrollHeight
of the webView:
extension WebView {
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if webView.isLoading == false {
webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, _) in
DispatchQueue.main.async {
self.parent.dynamicHeight = height as! CGFloat
}
})
}
}
}
}
It's working fine for small web views, but for very large web views (HTML passed directly into WKWebView to render), the initial scrollHeight
value returned from evaluateJavascript
is incorrect.
For instance, with the above self.parent.dynamicHeight
is returning 204187
when it should be 21675
.
If I wait 1 second after didFinish
to evaluate, it's returning the correct value of 21675
, using a temp async/await task:
extension WebView {
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if webView.isLoading == false {
Task.init {
do {
try await Task.sleep(nanoseconds: 1_500_000_000)
let result = try await webView.evaluateJavaScript("document.documentElement.scrollHeight")
self.parent.dynamicHeight = result as! CGFloat
} catch {
print(error)
}
}
}
}
}
}
While the above async task works, it's causing 1 second delays in rendering the Webview, and XCode is warning about WKWebView.evaluateJavaScript(_:completionHandler:) must be used from main thread only
.
Regardless, I don't understand how it's returning the incorrect scrollHeight
initially if didFinish
should execute after the webview is finished loading.
Safari inspection of the Webview shows the HTML and BODY both have the correct height size.
Is there something I'm missing?