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.
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
@IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "products", withExtension: "html")
let request = NSURLRequest(url: url! as URL)
webView.loadRequest(request as URLRequest)
}
@IBAction func closeDocumentViewer() {
displayView.isHidden = true;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
If I just one to receive a string from a javascript function what would I have to add to the above?
Apple is phasing out UIWebView, which is used by developers for integrating web content into an app in a quick and secure manner. Apple is replacing UIWebView (and WebView) with WKWebView, an updated version, as UIWebView has been deprecated.
It is supported in iOS and macOS, and by Mac Catalyst. Note: The App Store will no longer accept new apps that use UIWebView as of April 2020 and app updates that use UIWebView as of December 2020. Since iOS 12, Apple began warning developers about migrating to WKWebView, UIWebView's successor.
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.
As mentioned above, to load the web content in the iOS application, we can use the WebView object. All we need to do is, create a WKWebView object, set it as a view, and send it a request to load web content.
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
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With