Integrating the React Native Barcode Scanner SDK using Expo – a step-by-step tutorial

With our Ready-to-Use UI and the Expo framework, integrating barcode scanning functionalities into your React Native app only takes a few minutes. We’ll show you how it works!

Stefan September 17, 2024 9 mins read
app store

Setting up an app in React Native capable of scanning any 1D or 2D barcode is very straightforward. All we need are the following steps:

  1. Prepare the project
  2. Install the SDK
  3. Initialize the SDK
  4. Implement the scanning modes
  5. Build the app and scan some barcodes!

Thanks to our SDK’s Ready-to-Use UI Components, you can even use an AR overlay to display multiple barcodes’ contents right in the viewfinder.

Requirements

Before starting app development with React Native, you need to set up your local development environment. A real device is needed to get the full benefits from using our SDK. The steps for preparing your local environment for development can be found in the Expo documentation.

💡 Starting with React Native version 0.75, it’s recommended to use frameworks such as Expo to develop React Native applications. We’ll use Expo in this tutorial as well.

Of course, you can also integrate our SDK without a framework. For further information, please refer to the official React Native documentation.

1. Preparing the project

First, let’s create our Expo app using the Expo CLI, which will walk us through the setup process. To create an Expo app, run the following command in the terminal:

  npx create-expo-app@latest

Let’s open the project with your favorite code editor and prepare it to install the Scanbot SDK.

Remove boilerplate code

The Expo CLI has generated some screens to ensure the app isn’t empty. We can remove the generated code quickly by running the following command:

npm run reset-project

Now the app directory only contains an index file, which is our only screen, and a _layout.tsx file.

⚠️ Npm is the default package manager in this project, so we’ll be using it for this tutorial. Feel free to set up the project with other package managers supported by Expo.

Generate the native projects

To install expo-dev-client, we need to run the following command:

npx expo install expo-dev-client

After that, we generate our iOS and Android projects with:

npx expo prebuild

⚠️ If you are using a React Native Barcode Scanner SDK trial licence, make sure that the Android applicationId and iOS bundle identifier are the same.

2. Installing the SDK

Let’s install and configure the React Native Barcode Scanner SDK.

First we need to run:

npx expo install react-native-scanbot-barcode-scanner-sdk

Now that the npm package has been installed, all that’s left is to make the necessary native changes to the projects.

You can use our config plugin or manually configure the native projects. We’ll showcase both so you can pick the method you prefer.

Method A: Expo config plugin

To utilize the plugin, add the following to your app.json file:

"plugins": [
  "expo-router",
  [
    "react-native-scanbot-barcode-scanner-sdk",
    {
      "iOSCameraUsageDescription": "Camera permission is needed to scan barcodes",
      "androidCameraPermission": true,
      "androidCameraFeature": true,
      "mavenURLs": true
    }
  ]
],

Then run:

npx expo prebuild

Now we’re all set. You can skip the Android and iOS native changes when using this plugin.

Method B: Manual configuration

Alternatively, you can also apply the changes to the native projects manually.

Android

For Android, we first need to add the camera permissions in android/app/src/main/AndroidManifest.xml.

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

For development builds, we also need to add our Maven package URLs in android/build.gradle.

allprojects {
    repositories {
        ... other maven rpositories
      maven { url "https://nexus.scanbot.io/nexus/content/repositories/releases/" }
      maven { url "https://nexus.scanbot.io/nexus/content/repositories/snapshots/" }
    }
}

💡 For more information about individual releases, please refer to our changelog.

iOS

For iOS, we need to include a description for the camera permission in ios/{projectName}/Info.plist anywhere inside the element:

<key>NSCameraUsageDescription</key>
<string>Camera permission is needed to scan barcodes</string>

Now that the project is set up, we can start integrating the barcode scanning functionalities.

3. Initializing the SDK

Before using any feature of the React Native Barcode Scanner SDK, we need to initialize it. Ideally, initialization should be done as soon as the app is launched.

There are many ways to initialize the SDK that depend on your use case. In our example, we’re going to initialize the SDK inside a useEffect in our _layout.txt file.

ScanbotBarcodeSDK
  .initializeSdk({ licenseKey: "" })
  .then(result => console.log(result))
  .catch(err => console.log(err));

So the _layout.txt would look like this:

import { Stack } from "expo-router";
import { useEffect } from "react";
import ScanbotBarcodeSDK from "react-native-scanbot-barcode-scanner-sdk"

export default function RootLayout() {

useEffect(() => {
  ScanbotBarcodeSDK
    .initializeSdk({ licenseKey: "" })
    .then(result => console.log(result))
    .catch(err => console.log(err));
}, []);

  return (
    <Stack>
      <Stack.Screen name="index" />
    </Stack>
  );
}

💡 Without a license key, our SDK only runs for 60 seconds per session. This is more than enough for the purposes of our tutorial, but if you like, you can generate a license key using the bundle and application identifiers.

4. Implementing the scanning modes

Our RTU UI components make it easy to deploy our Barcode Scanner SDK’s different scanning modes in your app. Let’s start with the simplest use case: single-barcode scanning.

In app/index.tsx, we’re going to add a button that will start the scanning process. After we ran the reset project script, the index.tsx should only contain a single view with a text component. Let’s replace the Text component with a button component like this:

  <Button title={"Start single barcode scanning"} onPress={onSingleBarcodeScan} />

Now we need to define onBarcodeScannerPress, which will start the single-barcode scanning mode:

const onSingleBarcodeScan = useCallback(async () => {
  try {
    /** Check license status and return early if the license is not valid */
    if (!(await ScanbotBarcodeSDK.getLicenseInfo()).data?.isLicenseValid) {
      return;
    }
    /**
     * Instantiate a configuration object of BarcodeScannerConfiguration and
     * start the barcode scanner with the configuration
     */
    const config = new BarcodeScannerConfiguration();
    /** Initialize the use case for single scanning */
    config.useCase = new SingleScanningMode();
    /** Start the BarcodeScanner */
    const result = await startBarcodeScanner(config);
    /** Handle the result if result status is OK */
    if (result.status === 'OK' && result.data) {
      Alert.alert(
        "Barcode Scanning successfully!",
        `${result.data.items.map(barcode =>
          `Barcode value: ${barcode.text} and type: ${barcode.type}`
        ).join("\n")}`);
    } else {
      console.log("The user has canceled the Barcode Scanning")
    }
  } catch (e: any) {
    console.log("An error has occurred while running Barcode Scanner", e.message);
  }
}, []);

Our final screen should look like this:

import {Alert, Button, View} from "react-native";
import {useCallback} from "react";
import {
  BarcodeScannerConfiguration,
  SingleScanningMode,
  startBarcodeScanner
} from "react-native-scanbot-barcode-scanner-sdk/ui_v2";
import ScanbotBarcodeSDK from "react-native-scanbot-barcode-scanner-sdk";

export default function Index() {

  const onSingleBarcodeScan = useCallback(async () => {
    try {
      /** Check license status and return early if the license is not valid */
      if (!(await ScanbotBarcodeSDK.getLicenseInfo()).data?.isLicenseValid) {
        return;
      }
      /**
       * Instantiate a configuration object of BarcodeScannerConfiguration and
       * start the barcode scanner with the configuration
       */
      const config = new BarcodeScannerConfiguration();
      /** Initialize the use case for single scanning */
      config.useCase = new SingleScanningMode();
      /** Start the BarcodeScanner */
      const result = await startBarcodeScanner(config);
      /** Handle the result if result status is OK */
      if (result.status === 'OK' && result.data) {
        Alert.alert(
          "Barcode Scanning successfully!",
          `${result.data.items.map(barcode =>
            `Barcode value: ${barcode.text} and type: ${barcode.type}`
          ).join("\n")}`);
      } else {
        console.log("The user has canceled the Barcode Scanning")
      }
    } catch (e: any) {
      console.log("An error has occurred while running Barcode Scanner", e.message);
    }
  }, []);

  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <Button title={"Start single barcode scanning"} onPress={onSingleBarcodeScan}/>
    </View>
  );
}

Now we’re ready to start building our app and scan some barcodes. Let’s also add the multi-barcode scanning and AR overlay modes in the same way:

const onMultiBarcodeScan = useCallback(async () => {
  try {
    /** Check license status and return early if the license is not valid */
    if (!(await ScanbotBarcodeSDK.getLicenseInfo()).data?.isLicenseValid) {
      return;
    }
    /**
     * Instantiate a configuration object of BarcodeScannerConfiguration and
     * start the barcode scanner with the configuration
     */
    const config = new BarcodeScannerConfiguration();
    /** Initialize the use case for multi-scanning */
    config.useCase = new MultipleScanningMode();
    /** Start the BarcodeScanner */
    const result = await startBarcodeScanner(config);
    /** Handle the result if result status is OK */
    if (result.status === 'OK' && result.data) {
      Alert.alert(
        "Barcode Scanning successfully!",
        `${result.data.items.map(barcode =>
          `Barcode value: ${barcode.text} and type: ${barcode.type}`
        ).join("\n")}`);
    } else {
      console.log("The user has canceled the Barcode Scanning")
    }
  } catch (e: any) {
    console.log("An error has occurred while running Barcode Scanner", e.message);
  }
}, []);

const onAROverlayBarcodeScan = useCallback(async () => {
  try {
    /** Check license status and return early if the license is not valid */
    if (!(await ScanbotBarcodeSDK.getLicenseInfo()).data?.isLicenseValid) {
      return;
    }
    /**
     * Instantiate a configuration object of BarcodeScannerConfiguration and
     * start the barcode scanner with the configuration
     */
    const config = new BarcodeScannerConfiguration();
    /** Initialize the use case for multi-scanning */
    config.useCase = new MultipleScanningMode();
    /** Configure AR Overlay. */
    config.useCase.arOverlay.visible = true;
    config.useCase.arOverlay.automaticSelectionEnabled = false;
    /** Start the BarcodeScanner */
    const result = await startBarcodeScanner(config);
    /** Handle the result if result status is OK */
    if (result.status === 'OK' && result.data) {
      Alert.alert(
        "Barcode Scanning successfully!",
        `${result.data.items.map(barcode =>
          `Barcode value: ${barcode.text} and type: ${barcode.type}`
        ).join("\n")}`);
    } else {
      console.log("The user has canceled the Barcode Scanning")
    }
  } catch (e: any) {
    console.log("An error has occurred while running Barcode Scanner", e.message);
  }
}, []);

Finally, we need to add the buttons to start the scanning modes:

  <Button title={"Start multi-barcode scanning"} onPress={onMultiBarcodeScan}/>
  <Button title={"Start AR Overlay barcode scanning"} onPress={onAROverlayBarcodeScan}/>

5. Building the app and scanning some barcodes

We’re all done setting up our app.

To run the app on your Android or iOS device, use the following commands:

For Android:

npx expo run:android --device

For iOS:

npx expo run:ios --device

Now you can go ahead and scan 1D and 2D barcodes – one at a time, several at once, or with a real-time preview of their values via the AR overlay!

And if you’re in need of some sample barcodes for testing purposes, we’ve got you covered:

Various barcodes for testing

Conclusion

If this tutorial has piqued your interest in integrating barcode scanning functionalities into your React Native app, make sure to take a look at our SDK’s other neat features in our documentation or run our example project.

Should you have questions about this tutorial or ran into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.

Happy coding!