EGL Development User Group - Group home

Extend EGL cordova library

  

Extend EGL cordova library

            Example to integrate barcode scanner

 

We introduce EGL cordova library and tools in RBD 9.5 for EGL users to develop hybrid mobile app. Just like cordova itself, EGL cordova library is also open for extension. In this article, we will take barcode scanner as an example to demonstrate how to extend EGL cordova library. We will utilize the cordova plugin: phonegap-plugin-barcodescanner (https://github.com/phonegap/phonegap-plugin-barcodescanner) for this feature.

Create extended library project

The default EGL cordova library project is com.ibm.egl.rui.cordova_1.x.x for RBD 9.5.x. In order to extend it, we can either add the extended library into this project, or make another extended project. The latter is preferred as it is less coupled to the cordova widget and can be used even when EGL project has been updated.  The steps to create an extended widget project is:

  1. Create a new EGL RUI project. Name it like com.ibm.egl.rui.cordova.ext
  2. Right click the project, select Properties->EGL build path
    1. In projects tab, uncheck all dependencies. Then check com.ibm.egl.rui.cordova_1.x.x
    2. In order and exports tab, check com.ibm.egl.rui.cordova_1.x.x

By this way, the new project com.ibm.egl.rui.cordova.ext has included by linking to com.ibm.egl.rui.cordova_1.x.x, then the user can do the extension in this project.

Develop the extension

In this section, we will start to do the development. Prior to writing the code, the developer must get familiar with the plugins to be extended and think about how to design the corresponding API in EGL.

Create the EGL library

By learning the cordova plugin phonegap-plugin-barcodescanner, we know that it has 2 functions: scan and encode. To let the EGL developer use those functions, we will need to expose them in EGL. In this tutorial, we will take scan function as an example.

  1. In com.ibm.egl.rui.cordova.ext, create a new EGL library codova.BarcodescannerLib
  2. Define the library to add function scan. Please check the source code below

 

package cordova;

 

Delegate BarcodeScanSuccess(result ScanResult in) end

 

externalType BarcodescannerNative type JavaScriptObject{relativePath = "cordova", javaScriptName = "Barcodescanner"}

            function scan(onSuccess BarcodescanSuccess in, onError CordovaErrorHandler in, options ScanOption in);

end

// basic library

library BarcodescannerLib type BasicLibrary {}

           

            private barcodeScanner BarcodescannerNative{};

            function scan(onSuccess BarcodescanSuccess in, onError CordovaErrorHandler in, options ScanOption in)

                        barcodeScanner.scan(onSuccess, onError, options);

            end

           

end

 

record ScanResult

            text String;

            format String;

            cancelled boolean;

end

 

record ScanOption

            preferFrontCamaer boolean;

            showFlipCameraButton boolean;

            prompt String;

            formats String;

            orientation String;

end

 

The scan function is converted to EGL style. The callback function is defined as an EGL delegate. The options and result objects are also defined as EGL record. This file works like an interface from EGL to cordova.

 

Note that the externalType definition in the library, it defines an EGL javascript externaltype to delegate the implementation in the javascript.

 

Implement the externalType

As the externalType defined in the previous section, we will need to implement it in a Javascript file. Notice that, the javascript file path must match the definition relativePath and JavaScriptName like Webcontent/{relativePath}/{JavaScriptName}.js. In this case, the js file should be /com.ibm.egl.rui.cordova.ext/WebContent/cordova/Barcodescanner.js, the source code:

 

egl.defineClass("cordova", "Barcodescanner", {

            //convert result from js object to EGL ScanResult object

            "_convertResult" : function(o){

                        var r = new egl.cordova.ScanResult();

                        r.text = o.text;

                        r.format = o.format;

                        r.cancelled = o.cancelled;                  

                        return r;

            },

            //convert scanoptions from EGL object to js object

            "_optionsToObject" : function(o){

                        var a = {};

                        a.preferFrontCamaer = !!o.preferFrontCamaer;

                        a.showFlipCameraButton = !!o.showFlipCameraButton;

                        o.prompt!= null && (a.prompt = o.prompt);

                        o.formats!= null && (a.formats = o.formats);

                        o.orientation!= null && (a.orientation = o.orientation);

                       

                        return a;

            },

            "scan" : function(onSuccess, onError, options){

                        var _this = this;

                        cordova.plugins.barcodeScanner.scan(function(result){

                                    onSuccess(_this._convertResult(result));

                        }, function (error) {

                                    alert("Scanning failed: " + error);

                        }, _this._optionsToObject(options));

            }

});

 

It defined 2 helper functions to convert scan options and scan result. In the scan function, it calls cordova.plugins.barcodeScanner.scan to do the scan. This is the API provided by the plugin. By now, the extension is done.

 

Use the extended library

We will create a sample project to demonstrate the usage. The steps are

  1. Create a new EGL mobile project, com.ibm.egl.rui.cordova.ext.samples.
  2. Modify the EGL build path to depend on com.ibm.egl.rui.cordova.ext instead of the original cordova project com.ibm.egl.rui.cordova_1.x.x
  3. Create a RUI handler to write the sample

 

handler BarcodescannerSample type RUIhandler {initialUI = [ view ], title="BarcodescannerSample"}

           

            intro Div { margin = 20, font = "Arial", children = [                 

                        new HTML { text="This sample shows how to use the cordova BarcodescannerLib.", marginBottom=20}                 

                        ]

            };         

            View DojoMobileView{ headerTitle = "Barcodescanner Sample",

                                                children = [ intro, GridLayout ],           id = "BarcodescannerView"};

           

            GridLayout GridLayout{ margin = 20, cellPadding = 4, rows = 3, columns = 3,

                        children = [ Button, TextArea ] };

           

                       

            Button DojoMobileButton{ layoutData = new GridLayoutData{ row = 2, column = 1,

                        horizontalAlignment = GridLayoutLib.ALIGN_CENTER }, text = "Scan", onClick ::= Button_onClick };

                       

            TextArea DojoMobileTextArea{readOnly = true, layoutData = new GridLayoutData{ row = 3, column = 1, horizontalSpan = 3,

                        horizontalAlignment = GridLayoutLib.ALIGN_CENTER }, width=400, height=200};

                       

            function Button_onClick(event Event in)

                        BarcodescannerLib.scan(onScanSuccess, onError, new ScanOption{

                                    preferFrontCamaer = true

                        });

            end

 

            function onScanSuccess(a ScanResult in)

                        TextArea.value = ("Scan result text: " + a.text + " format: " + a.format + "\n" ) + TextArea.value;

            end

           

           

            function onError(message String in)

                        TextArea.value = ("get barcode scanner failed: " + message + "\n" ) + TextArea.value;

            end

           

           

end

 

Click the button will invoke the scan function and show the result in the textarea. Then we run it in the browser, but click the button fails. That’s because cordova functions are not for browsers. But it will be convenient if the user can preview the result in the browser before deploying it. We will learn about it in the next section.

Add the test proxy to run in browser

The default EGL cordova libraries are allowed to run in the browser for preview. It is also possible for extended plugins.

  1. Download the plugin source code, put it in com.ibm.egl.rui.cordova.ext/WebContent/runtime. For the barcode plugin, you will have com.ibm.egl.rui.cordova.ext/WebContent/runtime/phonegap-plugin-barcodescanner
  2. Inside phonegap-plugin-barcodescanner, delete all unused files. Leave www folder and src/browser folder
  3. Add the module header
    1. /src/browser/BarcodeScannerProxy.js cordova.define("phonegap-plugin-barcodescanner.BarcodeScannerProxy", function(require, exports, module) {  Remember to add } at the end.
    2. \www\barcodescanner.js cordova.define("phonegap-plugin-barcodescanner.barcodescanner", function(require, exports, module) {, and } in the end
  4. Define module
    • Copy cordova_plugins.js from com.ibm.egl.rui.cordova_1.x.x/webcontent to the current web content.
    • Add 2 moduels:

{

       "file": "runtime/phonegap-plugin-barcodescanner/www/barcodescanner.js",

       "id": "phonegap-plugin-barcodescanner.barcodescanner",

       "clobbers": [

           "cordova.plugins.barcodeScanner"

       ]

   },

   {

       "file": "runtime/phonegap-plugin-barcodescanner/src/browser/BarcodeScannerProxy.js",

       "id": "phonegap-plugin-barcodescanner.BarcodeScannerProxy",

       "runs": true

   },

Add to module.exports.metadata =

"phonegap-plugin-barcodescanner": "6.0.1"

 

By this way, you can now run in preview. The browserProxy will simulate the function for scan.

 

If you need to customized the simulated data, you can customized the /src/browser/BarcodeScannerProxy.js  to take advantage of the data in cordovaData.js.

 

Deploy consideration

The sample project can be deployed just the same as a common EGL cordova project. Just need to make sure

  1. During the creation of cordova project, make sure phonegap-plugin-barcodescanner plugin is selected and installed.
  2. Delete the /www/runtime folder in the deployed cordova project. It is brought by the extended cordova library project.

 

Notice that, for the phonegap-plugin-barcodescanner plugin, its android implementation has dependencies for zxing captureactivity jar. The user has to set the java build path for the cordova project. I have a built captureactivity jar attached.


Please check the attached file for the full code.

cordova-ext-barcode.zip