Introduction
Since its release in 2013, React has been gaining more and more traction in the world of software development. Reactive Design Pattern has become a well-known term in itself, although its origin was slightly controversial.
In 2015, Facebook’s development team delved into the world of mobile development and created its framework called React Native. As of the past few years, React Native has proven itself to be a formidable force in Cross-Platform Mobile Development. Let’s build a Scanbot Barcode Scanner App with React Native.
Getting Started with React
Tools
First off, React Native does not work magically. In layman’s terms, it’s just a blanket on top of a native iOS and Android app that offers a unified API for rendering views. Therefore, we require the same basic mobile development tools as if we were doing it in Java or Objective-C:
- Xcode & CocoaPods
- Android Studio
Then, it’s wise to have Java and path set in your way. If you’re on a clean installation of Android Studio and haven’t made any previous Java- or Gradle-related installs, it shouldn’t be necessary. This will let the React CLI know which Java to use if you’ve downloaded several versions of it. OpenJDK 8, which you can easily download and install, is the most beneficial option for Android development (11 should be fine, 14 is iffy with older versions of Gradle).
Then, on a Mac or Linux, go to /Users/$USER/ and open .bash_profile, .zshrc or .bashrc with your preferred text editor and add the following lines to it:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
export ANDROID_HOME=/Users/$USER/Library/Android/sdk
export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
After that, source <filename> to reload the file. That’s it!
Note that platform-tools have been added to the path as well. That is not required, but very handy for debugging all possible things, most notably, the command adb devices will show whether you have a debuggable device available or not.
And finally, the tools required for the React Native layer to properly function:
It is preferable to install everything through brew. The setup is quite simple. First, install brew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Then, make sure it’s up to date and install node:
brew update
brew install node
You’re now just about ready to start coding. One last hint from the official React Native environment setup guide:
React Native has a built-in command-line interface. Rather than install and manage a specific version of the CLI globally, we recommend you access the current version at runtime using npx, which ships with Node.js. With npx react-native <command>, the current stable version of the CLI will be downloaded and executed at the time the command is run.
Hello World!
The hard part was setting up the environment. From now on, the integration is going to be smooth sailing. We’ll be using typescript for this example, as it is the recommended approach for writing JavaScript these days. Run the following:
npx react-native init ScanbotApp --template react-native-template-typescript
That should take a couple of minutes, but it’s also an awesome one-liner that does everything for you: From creating and configuring the native projects to npm install. After this has been done, simply:
cd ScanbotApp
react-native run-android
Scanbot SDK
Now we finally get to the good stuff – Scanbot! If you’re reading this, you’re probably aware of what npm is; nevertheless, in short, your “Hello World” app has a file called package.json that defines all the dependencies you have. As you can see, React Native itself already defines a lot of them, everything from linters to typescript to jsx syntax.
Let’s add another one (to dependencies, not devDependencies, as we need the ScanbotSDK during runtime as well, not just for development purposes) and then install it via npm install:
"react-native-scanbot-sdk": "4.1.0"
iOS
Since the Scanbot SDK for React Native is a wrapper of the native version, an additional step is also to download the native SDK. As of React Native version 0.62, native dependencies are resolved automatically. You do not need to add anything to the Podfile (iOS native equivalent of package.json), but you still have to go to the iOS folder and install native dependencies:
cd ios
pod install
That was almost too easy, wasn’t it? Well, this isn’t over yet.
Android
As with most things in mobile development, you expect the android equivalent of something to be a bit more difficult to configure. This isn’t necessarily a bad thing, quite the opposite, having more options to configure is mostly a good a thing. It can get somewhat frustrating, though.
To configure Gradle-level requirements, we recommend using Android Studio, as it supports better syntax highlighting and a visual interface. You are, of course, free to use any text editor – even Notepad will do the trick.
First, you should enable MultiDex. That’s done via adding multiDexEnabled true to your android/app/build.gradle as such:
defaultConfig {
applicationId "com.scanbotapp"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled true
}
Enabling MultiDex is just a fancy way of saying “Yes, I know this app has a heavy-weight ML-based document scanning SDK and I don’t care”.
Right there in the same file, you should also specify that it should pick the first instance of libc++_shared.so that it finds, on the same level as defaultConfig, as follows:
packagingOptions {
pickFirst '**/libc++_shared.so'
}
This needs to be specified because many third-party dependencies have native binaries that use the c++ shared library (in the context of Gradle, React Native itself is a third dependency that uses it, and so does the Scanbot SDK).
Another thing you should add is android:largeHeap=”true” and that under your application tag of android/app/src/main/AndroidManifest.xml file, as such:
<application
android:largeHeap="true"
android:name=".MainApplication"
...
Next, you should also add Scanbot SDK paths to your application-level Gradle (android/build.gradle). That way, Gradle knows precisely where to find our SDK:
allprojects {
repositories {
...
// Scanbot SDK Maven repositories:
maven { url 'https://nexus.scanbot.io/nexus/content/repositories/releases/' }
maven { url 'https://nexus.scanbot.io/nexus/content/repositories/snapshots/' }
}
}
Right there in your application-level Gradle, you should also increase the minSdkVersion to 21, which is a requirement for the latest version of the Scanbot SDK (and, unless specifically requested otherwise, in general, a good idea – supporting backward compatibility below Android 5.0 is a nightmare).
And finally, specify where react-native-scanbot-sdk is located in your repository. That can be achieved by adding the following lines to android/settings.gradle:
include ':react-native-scanbot-sdk'
project(':react-native-scanbot-sdk').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-scanbot-sdk/android/app')
React-Native
If you’re using the same app template, you should also be able to do the following. For the sake of simplicity, slap a click-handler to the to a TextView, e.g. the following line:
<Text style={styles.sectionTitle} >Step One</Text>
becomes:
<Text
style={styles.sectionTitle}
onPress={() => {
console.log('Hello click-handler!');
}}>
Step One
</Text>
Then, let’s just create a global variable to decide what our click-handler should do:
let initialized = false;
Now that the basics are out of the way, it’s time to start working with the SDK.
Before you begin, you should define the imports. For this example, you just need three things: the SDK itself, and then two option and configuration classes:
import ScanbotSDK, {
BarcodeScannerConfiguration,
InitializationOptions,
} from 'react-native-scanbot-sdk/src';
The first real step is initialization. That goes as follows:
const options: InitializationOptions = {
licenseKey: '',
};
await ScanbotSDK.initializeSDK(options);
Similarly, to start the QR- and Barcode scanner, the snippet is as follows:
const configuration: BarcodeScannerConfiguration = {};
const result = await ScanbotSDK.UI.startBarcodeScanner(configuration);
Just to review, your entire onPress should look like this:
onPress={async () => {
if (!initialized) {
const options: InitializationOptions = {
licenseKey: '',
};
await ScanbotSDK.initializeSDK(options);
initialized = true;
Alert.alert("SDK initialized", "Press me again to start Barcode Scanner");
} else {
const configuration: BarcodeScannerConfiguration = {};
const result = await ScanbotSDK.UI.startBarcodeScanner(configuration);
if (result?.barcodes?.length > 0) {
Alert.alert("Barcode detected", result.barcodes[0].text);
}
}
}}>
Conclusion & References
While every cross-platform solution does have its problems, such as internal inconsistencies, React’s simplicity and elegance make software development very smooth and fun.
If you’d like to know more about the possibilities of React Native and the Scanbot SDK, check out the following links:
- Explore the features of Scanbot SDK in our example app
- Have a look at our extensive documentation
💡 Did you have trouble with this tutorial?
We offer free integration support for the implementation and testing of the Scanbot SDK. If you encounter technical issues or need advice on choosing the appropriate framework or features, join our Slack or MS Teams or send us an email to receive your free support.