Web Page Integration For QR Code Scanner With Acrobits Application

Overview

The main purpose of this document is to describe the flow and working of a feature through which any Web Page opened in the Acrobits Application can ask application to launch the QRCode Scanner and after scanning can receive the Data from the scanned QR Code.

For any Web Page to initiate the QRCode Scanning process from the Native Application, we need to understand the flow of Messages & Information among both. There are three layers involved to complete the process i.e.

  1. Javascript
  2. Web Page
  3. Native Application

Javascript

JavaScript layer is the key module that enables the communication between any Web Page and Native Application. This layer encapsulates all the communication logic and exposes the Interfaces that a Web Page needs to invoke to accomplish the communication. Acrobits has implemented this Layers which exposes the Interface for Web Page such that any Web Page can initiate the QRCode Scanning Process.

var softphone = {};

softphone.openQrCodeScanner = function(callback) {
    softphone.qrCodeCallback = callback;

    const userAgent = navigator.userAgent;

    if(/iPad|iPhone|iPod/i.test(userAgent)) {
        window.webkit.messageHandlers.softphoneOpenQrScanner.postMessage("");
    }
    else if(/android/i.test(userAgent)) {
        softphoneJsInterface.openQrScanner();
    }
    else {
        alert('Platform not supported');
    }
};

softphone.onQrCode = function(content) {
    if(content != null) {
        if (softphone.qrCodeCallback) {
            softphone.qrCodeCallback(content);
        }
    }
}

The above JavaScript exposes two interface methods i.e.

  1. softphone.openQrCodeScanner
  2. softphone.onQRCode

As their name suggests one represents the action to be taken and the later being the result of an action. Let’s discuss both, softphone.openQrCodeScanner is the method that would be invoked by any Web Page to initiate the QRCode scanning process. This method takes a parameter i.e. callback, this callback is a method that will be invoked later when application scans the QRCode and passes the scanned data back to Web Page. So make sure this callback method has a prototype that receives data as parameter.

Sofphone.onQrCode is another interface method that serves the communication from Native Application to Java Script Layer. This method actually receives the information from the Native Application and passes it to the Web Page via callback that is received when Web Page initiated the QRCode scanning process via softphone.openQrCodeScanner.

The above script is part of the Native Application which gets injected in the Web. Page being opened in the Web Browser Tab or anywhere within the Application.

Web Page

For a Web Page it should have some default Interface to initiate the message calls that can be handled by the underlying application. As described in the above section i.e. Java Script there are two Interface methods one being the initiator and second being the receiver. So following is an example of a simplest webpage which has a Text Field and a Button, Tapping on the Button will initiate the QRCode Scanning Request, which will be handled by the JavaScript Layer and based on the response received from the QRCode Scanning, the result will be displayed in the Text Filed.

<!DOCTYPE html>
<html>
    <body>
        <script>
            function callbackFunc(qrValue)
            {
                document.getElementById("qr").value = qrValue;
            }
        </script>
        <input type="text" name="qrcode" id="qr" />
        <br />
        <button onclick="softphone.openQrCodeScanner(callbackFunc)">Click me</button>
    </body>
</html>

The above sample code declares the function named callbackFunc which actually has a parameter which will contains the QRCode Scanned Data which is being set in the text filed named qr. The onclick listener for the button “Click me” is instantiating the QRCode Scanning Process via invoking the API Exposed by the Java Script Layer described the section Java Script. I.e. softphone.openQrCodeScanner(callbackFunc), here its passing the method as parameter which will be invoked by the Java Script layer to provide the Scanned QRCode Data.

Native Application

The Native Application has three responsibilities here:

  1. Inject the Java Script into the Web Page:
  2. Receive & Process the Message from Java Script:
  3. Send Result Back to Java Script:

Note: Here we shall be giving the example of iOS Application using Objective-C Code.

Inject the Java Script into the Web Page

This is the first step involved which enables the communication among the Web Page and Native Application. Following is the code snippet which loads the script file named softphone.js form the target and inject it in the Web Page being loaded.

WKWebViewConfiguration *webViewConfigurations = [[WKWebViewConfiguration alloc] init];
NSString *path = [[NSBundle mainBundle] pathForResource:@"softphone" ofType:@"js"];
if (path)
{
    NSError *error = nil;
    NSString *source = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if (!error)
    {
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        webViewConfigurations.userContentController = userContentController;
        WKUserScript *userScript = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        [userContentController addUserScript:userScript];
    }
}
[[WKWebView alloc] initWithFrame:CGRectZero configuration:webViewConfigurations];

The above code snippet creates the instance of WKWebViewConfiguration and WKUserContentController, then instantiate the WKUserScript using the Java Script loaded from softphone.js and in the end instantiate the Instance of WKWebView using the WKWebViewConfiguration instance.

Receive & Process the Message from Java Script

To receive the Message from Java Script application need to implement the message handler for this:

[userContentController addScriptMessageHandler:self name:@"softphoneOpenQrScanner"];

The above line will configure the WebBrowser class to receive the message calls initiated from the Java Script i.e. softphoneOpenQrScanner

To process the message the WKScriptMessageHandler provides the delegate method i.e.

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    if ([message.name isEqualToString:@"softphoneOpenQrScanner"])
    {
        // Process the message call here
    }
}

Send Result Back to Java Script

To pass the result back to Java Script Layer so that it can be passed back to the Web Page, application need to invoke the Interface Method that is exposed in the Injected Java Script described in the section above i.e. soft phone.onQrCode. This method takes the parameter that would be the scanned QR Code data. On iOS WKWebView has a method evaluateJavaScript which can be invoked to initiate the Injected Java Script Method Call i.e.

NSString *value = @"Scanned QRCode Data";
NSString *function = [[NSString alloc] initWithFormat: @"softphone.onQrCode('%@')", value];
[_webView evaluateJavaScript:function completionHandler:nil];