Javascript call to Swift from UIWebView
You must a custom URL Scheme
such as myawesomeapp
and intercept requests to it using:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: 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 UIWebView
s here: JavaScript synchronous native communication to WKWebView
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
class ViewController: UIViewController, WKScriptMessageHandler {
var webView: WKWebView?
override func loadView() {
super.loadView()
webView = WKWebView(frame: self.view.frame)
webView?.configuration.userContentController.add(self, name: "scriptHandler")
self.view.addSubview(webView!)
}
public func userContentController(_ userContentController: WKUserContentController, didReceive message: 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 = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
// success callback
}, function(error) {
// error callback
});