Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Implement A Barcode Scanner Using Telerik NativeScript

TwitterFacebookRedditLinkedInHacker News

So you’re getting some fancy new features into your NativeScript Android and iOS application. A feature I always find to be useful is having a barcode scanner within my app. Barcodes are a convenient way to pass around information without having to type it in. With NativeScript we can easily add scanning features to our application.

We’re going to see how to create a NativeScript Android and iOS application that can scan different types of barcodes.

Let’s start by creating a fresh NativeScript project. This can be done by executing the following from a Command Prompt (Windows) or Terminal (Mac and Linux):

tns create BarcodeProject --template tsc
cd BarcodeProject
tns platform add ios
tns platform add android

Something important to note here. If you’re not using a Mac computer then you cannot add and build for the iOS platform.

You might have also noticed the --template tsc flag. This means that our project will be using TypeScript rather than JavaScript. You are definitely able to apply this guide towards a JavaScript project as well.

With that said, we now need to install the plugin that will give us barcode scanning support. We are going to use the nativescript-barcodescanner plugin by Eddy Verbruggen. We don’t need to use a NativeScript plugin, but due to the complexity of the barcode scanner library it is probably a good idea. To install the plugin, execute the following:

tns plugin add nativescript-barcodescanner

It is time to crack open our code.

We’re going to spend most of our time in the app/main-page.xml and app/main-page.ts files, but first we need to include the TypeScript definitions file in our project so we don’t get compile time errors.

Open the project’s references.d.ts file and include the following line:

/// <reference path="./node_modules/nativescript-barcodescanner/barcodescanner.d.ts" /> Needed for autocompletion and compilation.

Now we can start the good stuff.

Starting with our logic file, open the project’s app/main-page.ts file and include the following code:

import barcodescannerModule = require("nativescript-barcodescanner");

export function requestPermission() {
    return new Promise((resolve, reject) => {
        barcodescannerModule.available().then((available) => {
            if(available) {
                barcodescannerModule.hasCameraPermission().then((granted) => {
                    if(!granted) {
                        barcodescannerModule.requestCameraPermission().then(() => {
                            resolve("Camera permission granted");
                        });
                    } else {
                        resolve("Camera permission was already granted");
                    }
                });
            } else {
                reject("This device does not have an available camera");
            }
        });
    });
}

export function scanBarcode() {
    requestPermission().then((result) => {
        barcodescannerModule.scan({
            cancelLabel: "Stop scanning",
            message: "Go scan something",
            preferFrontCamera: false,
            showFlipCameraButton: true
        }).then((result) => {
            console.log("Scan format: " + result.format);
            console.log("Scan text:   " + result.text);
        }, (error) => {
            console.log("No scan: " + error);
        });
    }, (error) => {
        console.log("ERROR", error);
    });
}

A lot is happening in the above so we’re going to break it down.

First we need to include the module in our project like so:

import barcodescannerModule = require("nativescript-barcodescanner");

Next we have two functions. Because newer versions of iOS and Android require that you first request permission we need to do so before trying to scan. For convenience my goal here was to check for permission every time someone tries to scan. This is why the requestPermission function exists separately.

export function requestPermission() {
    return new Promise((resolve, reject) => {
        barcodescannerModule.available().then((available) => {
            if(available) {
                barcodescannerModule.hasCameraPermission().then((granted) => {
                    if(!granted) {
                        barcodescannerModule.requestCameraPermission().then(() => {
                            resolve("Camera permission granted");
                        });
                    } else {
                        resolve("Camera permission was already granted");
                    }
                });
            } else {
                reject("This device does not have an available camera");
            }
        });
    });
}

The above function returns a Promise so we can scan only when a success response is triggered. We first make sure the device has a camera. If it does, we check to see if we have already been granted permission. If yes, then we can resolve the promise, and if no we can request permission.

export function scanBarcode() {
    requestPermission().then((result) => {
        barcodescannerModule.scan({
            cancelLabel: "Stop scanning",
            message: "Go scan something",
            preferFrontCamera: false,
            showFlipCameraButton: true
        }).then((result) => {
            console.log("Scan format: " + result.format);
            console.log("Scan text:   " + result.text);
        }, (error) => {
            console.log("No scan: " + error);
        });
    }, (error) => {
        console.log("ERROR", error);
    });
}

Above is our scan function. First we request permission from the previous function and if it resolves as true we can scan, otherwise show an error. The scan results will contain the format of the barcode and the value.

In terms of what barcode formats are supported, iOS can scan the following:

  • Code39
  • Code93
  • Code128
  • EAN8
  • EAN13
  • QR
  • UPC_E
  • Aztec
  • PDF417

Android can scan the following formats:

  • Code39
  • Code93
  • Code128
  • EAN8
  • EAN13
  • QR
  • UPC_E
  • DATA_MATRIX
  • CODABAR
  • ITF
  • RSS14
  • UPC_A

This NativeScript plugin uses the pretty standard ZXing library that is used in most applications when it comes to Android. For iOS, Eddy made a wrapper.

With the TypeScript logic in place we can add our very simple UI. Open app/main-page.xml and include the following code:

<Page xmlns="http://schemas.nativescript.org/tns.xsd">
    <StackLayout>
        <Button text="Scan Barcode" tap="scanBarcode" />
    </StackLayout>
</Page>

You can see there is nothing fancy here. Just a single button that starts our permission requests and scanning. All output is sent to the logs in this example.

Conclusion

You just saw how to create a NativeScript Android and iOS application, based in TypeScript, that can scan popular barcodes. You can add functionality in your app to fill forms based on the scan or whatever else you can think of. I, for example, have an application that stores time based one-time passwords. The password secret key is added to the application via scanning a QR code. Just one of many possible examples that would benefit from a barcode scanner.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.