OneSpan Sign Developers: Web View Support in iOS Devices
In order to integrate OneSpan Sign New Signer Experience to your mobile application, mobile developers have flexible options, such as utilizing the OneSpan Sign Mobile SDKs or simply directly present the signing ceremony in a web view.
In the last blog of this series, we demonstrated how to add a WebView to your Android mobile app and fully control the signing flow by monitoring the Javascript Event Notifier. Picking up there, we will showcase how to implement the same feature for iOS devices. Without further delay, let’s get started!
Prerequisites
To help facilitate today’s training, make sure to complete the following tasks:
- Enable New Signer Experience in your account
- Download the sample code from this Code Share
The sample code showcased in this blog is an Xcode project in Swift. If it’s your first time building an iOS app, go over this Apple Tutorial first. In the following sections, we will break down the sample code into pieces. Follow the explanations below and adjust the code accordingly.
Step 1: The Basics of WKWebView
iOS provides different ways to present an external web view, and the one we will covered in this example is WKWebView which is a part of the WebKit framework. The WKWebView API renders a complete mobile browser experience as a seamless part of your app’s UI by loading a view that leverages existing HTML, CSS, and JavaScript content.
Below is a simple example of how you can create a web view and make it fill all available space:
import UIKit import WebKit class WebViewController: UIViewController { private var webKitView: WKWebView! public var url: URL? override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() webKitView = WKWebView(frame: self.view.frame, configuration: config) if let signingURL = url { webKitView.load(URLRequest(url: signingURL)) } } }
Step 2: Handle Javascript Notifier
It is already sufficient to display the New Signer Experience with Step 1. However if you want to further be notified with the signing status change like when a signer completed signing, and to fully control the signing flow, you can enable the Javascript and customize the WKWebView with the code below:
webKitView.configuration.preferences.javaScriptEnabled = true
When an event of interest is triggered, the OneSpan Sign server sends the notification through Webkit:
window.webkit.messageHandlers.{messageHandlerName}.postMessage({messageBody})
This JavaScript code specifically targets your message handler and calls your handler’s userContentController(_:didReceive:) method. Similar to the OneSpan Sign Javascript Event Notifier in desktop browser, you can configure your system to listen to “ESL:MESSAGE:REGISTER” event and then send back “ESL:MESSAGE:ACTIVATE_EVENTS” message in order to receive further notifications. In our code, the first switch case explicitly tells OneSpan Sign that we want to register for event listening.
extension WebViewController : WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if let eslMessage = message.body as? String{ if (eslMessage == "ESL:MESSAGE:REGISTER"){ webKitView.evaluateJavaScript("window.parent.postMessage('ESL:MESSAGE:ACTIVATE_EVENTS');", completionHandler: nil) } print("\(eslMessage)") } } }
At the end, don’t forget to install your message handler where the implied message handler name is “message”:
config.userContentController.add(self, name: "message")
Step 3: Handle Document Download
Once tapping on the download button, New Signer Experience will navigate the web view to a blob URL. To better handle the document download, we could Implement the methods of WKNavigationDelegate protocol in order to track the progress of navigation requests and provide a customized download function:
extension WebViewController : WKNavigationDelegate webKitView.navigationDelegate = self
In particular, we will override the “didFinish” and “decidePolicyFor” events:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("sessionStorage.getItem(\"session\")") { (result, error) in print("Session Storage: ", result ?? "") } } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url { if url.absoluteString.contains("blob") { print("DOWNLOAD ACTION") let rightSideOptionButton = UIBarButtonItem(title: "Download", style: .plain, target: self, action: #selector(onDownload)) self.navigationItem.rightBarButtonItem = rightSideOptionButton } } decisionHandler(.allow) }
Test the Code
After filling in the stub functions left in the sample code, you are ready to run the app on a real device or an emulator. You can go ahead and finish up the signing, navigate through the documents, click download buttons, zoom in and out the page, decline signing, and perform as many test cases as you want.
In particular, there are few things you need to pay attention to in the console log:
- You should be able to find the initial event notification “ESL:MESSAGE:REGISTER” the first time loading the signing ceremony.
- Other event notifications like signer complete (“ESL:MESSAGE:SUCCESS:SIGNER_COMPLETE”), signer decline (“ESL:MESSAGE:SUCCESS:PACKAGE_DECLINE”) should function well and thus your app is able to control the signing flow.
- When you clicked on the download buttons, the “decidePolicyFor” event should be able to invoke the stub function and perform download operations.
There it is. Through today’s blog, you should be able to implement a WKWebView in Xcode project, install a Javascript message handler, and handle the document download. If you have any questions regarding this blog or anything else concerning the integration of OneSpan Sign into your application, visit the Developer Community Forums. Your feedback matters to us