If you're considering updating your app's web view, I highly recommend switching to WKWebView
over UIWebView
. By using WKWebView, you can avoid the need to register a custom URL scheme. Moreover, WKWebView offers significant advantages, particularly in terms of performance and rendering since it operates in a separate process.
You can find more information and Apple's official recommendation for using WKWebView at this link:
Apple Documentation on WKWebView
Note:
As of iOS 8.0 and OS X 10.10, it is advised to utilize WKWebView instead of UIWebView or WebView for incorporating web content into your application.
Creating a native to JavaScript bridge with WKWebView is straightforward:
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("Received Message: \(message.name) with body: \(message.body)")
}
// remaining code
}
In your JavaScript code, you can then call it like so:
window.webkit.messageHandlers["scriptHandler"].postMessage("hello");
I have developed a library that enhances this functionality and introduces some advanced JavaScript syntax.
GitHub Repository for BridgeCommander
To integrate it, simply reference the project (or include the Swift and JavaScript files in your Xcode project) and execute the following steps:
webView = WKWebView(frame: self.view.frame)
let commander = SwiftBridgeCommander(webView!)
commander.add("echo") {
command in
command.send(args: "You said: \(command.args)")
}
This will enable you to use callback syntax in JavaScript as demonstrated below:
var commander = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
// success callback
}, function(error) {
// error callback
});