I'm trying to catch every onClick
event in WKWebView
.
The website is working only with JavaScript so I cannot handle anything in:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
How can I do this?
Inject JavaScript to WKWebView with WKUserScript viewDidLoad() let config = WKWebViewConfiguration() let js = getMyJavaScript() let script = WKUserScript(source: js, injectionTime: . atDocumentEnd, forMainFrameOnly: false) config. userContentController. addUserScript(script) config.
A message handler is a listener that will fire and return data once some JavaScript event completes. For example, you can have a handler to parse JSON data fetched from a URL. By including these message handlers into your WKUserContentController object, your web view will define a new function window. webkit.
Overview. A WKUserContentController object provides a bridge between your app and the JavaScript code running in the web view. Use this object to do the following: Inject JavaScript code into webpages running in your web view. Install custom JavaScript functions that call through to your app's native code.
The old one – UIWebView is considered insecure and should no longer be used. WKWebView is the right API to implement WebViews. Unfortunately, using even the modern API may lead to vulnerabilities. Developers have to make sure that their code is not vulnerable to both web-related and native attacks.
you can use a WKUserScript and add it to the userContentController of the WKWebView's configuration.
let config = WKWebViewConfiguration()
let source = "document.addEventListener('click', function(){ window.webkit.messageHandlers.iosListener.postMessage('click clack!'); })"
let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
config.userContentController.addUserScript(script)
config.userContentController.add(self, name: "iosListener")
webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
this will make the script and inject it into the page when the document is finished loading. Now, you need to implement the WKScriptMessageHandler protocol to receive the message:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("message: \(message.body)")
// and whatever other actions you want to take
}
If you want to add click listener only for button with id 'buttonX' (<button id="buttonX">Click me</button>
) then
let scriptSource = """
var button = document.getElementById('buttonX');
document.body.style.backgroundColor = `red`;
if(button != null) {
button.addEventListener("click", function(){
window.webkit.messageHandlers.iosClickListener.postMessage('open_invitation');
document.body.style.backgroundColor = `green`;
});
}
"""
let config = WKWebViewConfiguration()
let script = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
config.userContentController.addUserScript(script)
config.userContentController.add(self, name: "iosClickListener")
let webView = WKWebView(frame: view.frame, configuration: config)
view.addSubview(webView)
webView.loadHTMLString(html, baseURL: nil) //load your html body here
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let body = message.body as? String, body == "open_invitation" {
print("✅ we did it")
}
}
Also your view controller should conform to WKScriptMessageHandler
protocol
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With