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
final class ViewController: UIViewController, WKScriptMessageHandler {
private var webView: WKWebView?
override func loadView() {
super.loadView()
let webView = WKWebView(frame: self.view.frame)
webView.configuration.userContentController.add(self, name: "scriptHandler")
self.webView = webView
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
});