Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 821
nachshon f Avatar asked Dec 18 '17 00:12

nachshon f


People also ask

Can you use JavaScript with Swift?

The JavaScriptCore framework provides the ability to evaluate JavaScript programs from within Swift, Objective-C, and C-based apps. You can use also use JavaScriptCore to insert custom objects into the JavaScript environment.

What is the difference between UIWebView and WKWebView?

Unlike UIWebView, which does not support server authentication challenges, WKWebView does. In practical terms, this means that when using WKWebView, you can enter site credentials for password-protected websites.

How do I use WKWebView?

Here's how: Open the XIB or Storyboard you want to add the web view to in Interface Builder. Find the web view or WKWebView in the Object Library at the bottom-left of Interface Builder. Drag-and-drop a WKWebView object from the Object Library to your view controller's canvas, and adjust its size and position.

What is WKWebView?

A WKWebView object is a platform-native view that you use to incorporate web content seamlessly into your app's UI. A web view supports a full web-browsing experience, and presents HTML, CSS, and JavaScript content alongside your app's native views.


1 Answers

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"]
    }
}
like image 173
koropok Avatar answered Sep 29 '22 23:09

koropok