I am trying to solve problem with communication between WebView and Javascript.
What I know
I can listen to message handler functions with code like this: Website javascript code:
webkit.messageHandlers.loginServiceReady.postMessage('TEST')
Swift - WebView code:
// Register
userContentController.add(coordinator, name: "loginServiceReady")
// Set reaction when function triggers
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage
) {
print(message.body)
let date = Date()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.messageToWebview(msg: "HELLO, I got your messsage: \(message.body) at \(date)")
}
}
(this is well epxlained in this video + github link in description: https://www.youtube.com/watch?v=t0bKurq_Apk)
My goal
I want to listen for function and for the moment when the website triggers it in webview similarly to previous case, but without message body and with different function structure:
Website javascript code I want to listen for:
NativeApp.loginServiceReady()
and after this happening trigger some swift code.
(I can't change this web javascript code) (I need to wait for website to trigger the function, so using webView.evaluateJavaScript doesnt solve this issue)
Is that possible? I know it's possible on android by using: @JavascriptInterface and AddJavascriptInterface. I spent several hours trying to solve this and read probably half of the internet, your help will be much appreciated!
evaluateJavaScriptdoes not work for you. You inject your code into JS usingwebView.evaluateJavaScript. The code itself replicates whatever Android'sAddJavascriptInterfaceis doing (for example you can inject a new function with the same name, which will override the original function, see this for example). Yes, this approach is a bit shady: some issues may arise with container isolation, not to mention the legal aspects of altering web site's code... But it is the only way IMO