Skip to content Skip to sidebar Skip to footer

Javascript Call To Swift From Uiwebview

I am trying to make a call from a javascript function in a UIWebView to Swift in iOS 10. I have setup a very basic project just to try and get this working, the code is below. imp

Solution 1:

I would suggest looking into using WKWebView instead UIWebView. You then won't need to register custom URL scheme. Additionally, UIWebView is obsolete and WKWebView has a lot of advantages, most notably performance and rendering as it runs in a separate process.

Link to Apple documentation and recommendation to use WKWebView https://developer.apple.com/reference/webkit/wkwebview/

Important

Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your > app. Do not use UIWebView or WebView.

That said, it's very simple to setup a native to javascript bridge:

import WebKit

classViewController: UIViewController, WKScriptMessageHandler {
   var webView: WKWebView?
    overridefuncloadView() {
        super.loadView()
        
        webView =WKWebView(frame: self.view.frame)
        webView?.configuration.userContentController.add(self, name: "scriptHandler")
        
        self.view.addSubview(webView!)
    }
    
    publicfuncuserContentController(_userContentController: WKUserContentController, didReceivemessage: WKScriptMessage) {
        print("Message received: \(message.name) with body: \(message.body)")
    }
// rest of code
}

Then in your javascript code, call it:

window.webkit.messageHandlers["scriptHandler"].postMessage("hello");

I have written a library that leverages this and adds some fancy javascript syntax. https://github.com/tmarkovski/BridgeCommander

To use it, just reference the project (or add the swift and javascript files to your Xcode project) and call

    webView =WKWebView(frame: self.view.frame)
    let commander =SwiftBridgeCommander(webView!)
    
    commander.add("echo") {
        command in
        command.send(args: "You said: \(command.args)")
    }

You then will be able to use callback syntax in javascript like this

var commander = newSwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
        // success callback
    }, function(error) { 
        // error callback
});

Solution 2:

You must a custom URL Scheme such as myawesomeapp and intercept requests to it using:

funcwebView(webView: UIWebView, shouldStartLoadWithRequestrequest: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool

Fire a call to native code using window.location=myawesomeapp://hello=world, and get the query params you pass from request.URL.query in the native code.

For more information, see my question about UIWebViews here: JavaScript synchronous native communication to WKWebView

Solution 3:

We can call the swift function from Javascript with the help of WKScriptMessageHandler

A class conforming to the WKScriptMessageHandler protocol provides a method for receiving messages from JavaScript running on a webpage.

we need to add a listener to the event into our WKUserContentController

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

We have to implement its userContentController to receive the content sent from Javascript. for ex. limiting only to the "logout" we want for now.

funcuserContentController(_userContentController: WKUserContentController, didReceivemessage: WKScriptMessage) {       
       if message.name =="logout" {
           print("JavaScript is sending a message \(message.body)")
       }
   }

And from JavaScript end, They have to implement like this:

functionsendLogoutAction() {
       try {
           webkit.messageHandlers.logout.postMessage("logout");
       } catch(err) {
           console.log('The native context does not exist yet');
       }
    }

Post a Comment for "Javascript Call To Swift From Uiwebview"