I am developing a swift ios app that uses WKWebView to load up an ecommerce site.
When a user purchases a product here, the checkout page allows the user to pay in cryptocurrency.  
When the user clicks "Open in Wallet", the site shoots off a 
window.postMessage(paymentData) 
where payment data is a js object with a bitcoin url in it. 
I am using a WKUserScript with WKWebConfiguration to inject a script that listens for a window message and then fires off data to my webkit.messageHandler.  
let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """
Unfortunately this code never triggers.
When I use chrome or safari devtools to inject the same javascript, it works just fine.
I have scoured stack overflow to see if there is a special condition for window.postMessage in WKWebView but have had no luck thus far. 
Is it possible to capture a window.postMessage() event and pipe the event data back to my ios app?
Thanks in advance!!!! Here is my existing code.
  let webConfiguration = WKWebViewConfiguration()
    let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """
    let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
    userContentController.addUserScript(script)
    userContentController.add(self, name: "iosListener")
    webConfiguration.userContentController = userContentController
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    webView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(webView)
 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print("message body: \(message.body)")
    print("message frameInfo: \(message.frameInfo)")
  }
                Yes, it is possible. You also need to set javascriptEnabled = true
self.webView.configuration.preferences.javaScriptEnabled = true
You can also configure the listener like this:
self.webView.configuration.userContentController.add(self, name: "iosListener")
And make sure you're applying both commands before
self.webView.load(/*some request*/)
You can make a simple test after the page didFinish loading with:
self.webView.evaluateJavaScript("window.webkit.messageHandlers.iosListener.postMessage('test');", completionHandler: { (result, err) in
    if (err != nil) {
        // show error feedback to user.
    }
})
Another advice is to always have ; at the end of commands on javascript code when interacting with webView as some can rely on standard javascript.
let source = """
    window.addEventListener('message', function(e) {
        window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data));
    });
    """
Note: I'd also suggest to have the webView as a class variable instead of a method variable, you're probably creating it on viewDidLoad(), I'd suggest that you move the variable to your class.
var webView: WKWebView!
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