nachshon f
nachshon f

Reputation: 3680

How do I communicate from JS to Swift

I'm creating a hybrid app and I'm trying to figure out how to pass some data from the WKWebView to the native app.

I've been trying to figure this out for days and I can't seem to find anything! There seems to be very little info online about this, and everything I do find, is the other way around (Swift to JS, not JS to Swift).

I've tried using URL variables, but the Webview has to reload for Swift to recognize that it changed. I tried using WKScriptMessageHandler, but I can't find any good documentation about it, and it seems very complicated.

There must be some easy way to accomplish this. Any ideas?

I would be really grateful to anyone who can help me with this.

Upvotes: 8

Views: 5471

Answers (1)

koropok
koropok

Reputation: 1413

It's not that complicated actually.

Firstly you have to add the script message handler into the content controller.

let contentController = WKUserContentController()
contentController.add(self, name: "derp") //name is the key you want the app to listen to.

Next up you have to assign the content controller into the configuration.

let config = WKWebViewConfiguration()
config.userContentController = contentController

then you need to assign the configuration to your web view.

let webView = WKWebView(frame: CGRect.zero, configuration: config) //set your own frame

and for the JS side.

var message = {'fruit':'apple'};
window.webkit.messageHandlers.derp.postMessage(message);

Lastly you have to let your view controller (I'm assuming that the webView is in a view controller) conform to the WKScriptMessageHandler protocol. I've added the rest of the codes into a sample view controller as requested.

class MyViewController: UIViewController, WKScriptMessageHandler {

    override func viewDidLoad() {

        super.viewDidLoad()

        let contentController = WKUserContentController()
        contentController.add(self, name: "derp")

        let config = WKWebViewConfiguration()
        config.userContentController = contentController

        let webView = WKWebView(frame: self.view.frame, configuration: config) //you can consider using auto layout though
        self.view.addSubview(webView)

        //load your url here 
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

        //handle script messages here
        //message.name is "derp"
        //message.body is ["fruit":"apple"]
    }
}

Upvotes: 11

Related Questions