React Native app tutorial: How to integrate our scanning functionalities

app store

Getting started

Requirements

For Android apps

For iOS apps

Create a “Hello World” React Native ap

$ npx react-native init my_awesome_react_native_app

This command will create a blank React Native app. 

Test run

Next, let’s connect a mobile device via USB and run the app.

Android

$ cd my_awesome_react_native_app/
$ npx react-native run-android

iOS

$ cd my_awesome_react_native_app/

Or open my_awesome_react_native_app/ios/my_awesome_react_native_app.xcworkspace in Xcode and adjust the “Signing & Capabilities” settings by selecting your Apple developer account. Then select your target device and hit the “Run” button.

On both Android and iOS, you should now see the same app with a “Welcome to React Native” screen.

Add the Scanbot SDK

Now let’s add the Scanbot SDK to our project. The Scanbot SDK for React Native is available as the NPM package react-native-scanbot-sdk. Use the following command to install it:

$ npm install react-native-scanbot-sdk

Next, we’ll adjust a few platform-specific settings for both Android and iOS.

Android settings

The Scanbot SDK for React Native is based on the native Scanbot SDK for Android, which is distributed through private Maven repositories. We need to add these repositories in our android/build.gradle file in the section allprojects > repositories:

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/' }
    }
}

Add SDK Project Reference

As of react-native v0.62, a Scanbot SDK reference needs to be added to the file android/settings.gradle like so:

rootProject.name = 'my_awesome_react_native_app'
...
include ':react-native-scanbot-sdk'
project(':react-native-scanbot-sdk').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-scanbot-sdk/android/app')

Enable MultiDex

Make sure you have enabled multidex by setting multiDexEnabled to true in our android/app/build.gradle file:

android {
  ...
  defaultConfig {
    ...
    multiDexEnabled true
  }
}

Also add the following config in the same build.gradle file to avoid conflicts with the library filename libc++_shared.so, which is used by React Native as well as by many other 3rd-party modules:

android {
  ...
  packagingOptions {
    pickFirst '**/libc++_shared.so'
  }
}

Tuning the Android Manifest

Since our application will work with high-resolution images, it’s best to add the property android:largeHeap="true" in the <application> element of our android/app/src/main/AndroidManifest.xml file, especially for Android <= 7.x. Processing hi-res images is a memory-intensive task, and this property will ensure our app has enough heap allocated to avoid OutOfMemoryError exceptions.

<application ... android:largeHeap="true">
  ...
</application>

In the same AndroidManifest.xml file, we need to declare that our app uses the camera and hence requires the CAMERA permission:

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

iOS Settings

In your ios/Podfile, add the RNScanbotSDK pod:

pod 'RNScanbotSDK', :path => '../node_modules/react-native-scanbot-sdk'

Then, reinstall the pods by running:

$ cd ios/
$ pod install --repo-update


And finally, we need to add the required NSCameraUsageDescription property in Xcode in the Info settings tab of the project (which corresponds to the Info.plist file):

NSCameraUsageDescription "Privacy - Camera Usage Description"

As the value, enter a brief description of why your app needs access to the camera, e.g. “Camera access is required to scan documents.”

Scanbot SDK:
Unlimited scanning at a fixed price

Your reliable data capture solution for mobile and web app integration.


Supports all common platforms and frameworks.

It’s coding time

Now that the preliminary settings are taken care of, it’s time to write some actual code for our app.

Initial Code

First, we will import the Scanbot SDK into our app. We’ll also create a basic React component to hold our Document Scanner.

To do so, replace the content of the file App.js with the following code:

import React from 'react';
import {SafeAreaView, View, Button, Image} from 'react-native';
import ScanbotSDK, {
  DocumentScannerConfiguration,
  InitializationOptions,
} from 'react-native-scanbot-sdk';

class App extends React.Component {
  constructor(props: any) {
    super(props);
    this.imageFileUri = null;
  }

  render() {
    return (
      <SafeAreaView>
        <View style={{padding: 30}}>
        </View>
      </SafeAreaView>
    );
  }
}

export default App;

Initialize the Scanbot SDK

The Scanbot SDK must be initialized before usage. For this, we use the SDK API method ScanbotSDK.initializeSDK(options)

Let’s put a simple function named initScanbotSDK() in our new App class in App.js:

class App extends React.Component { 
... 
 async initScanbotSDK() {
    const options: InitializationOptions = {
      licenseKey: '', // see the license key notes below!
      loggingEnabled: true,
    };
    let result = await ScanbotSDK.initializeSDK(options);
    console.log(result.result);
  }
...
}

Call this function in the constructor of our class component:

constructor(props: any) {
  super(props);
  this.imageFileUri = null;
  this.initScanbotSDK();
}

For the full API reference of the React Native Scanbot SDK, please check out the documentation.

Integrate the Document Scanner UI

The Scanbot SDK for React Native provides a scanner UI for document scanning. The Document Scanner is a complete and ready-to-use screen component and can be easily integrated with just a few lines of code using the API method ScanbotSDK.UI.startDocumentScanner(config).

Let’s put the SDK call in a simple function named scanDocument() so we can bind it to a button:

class App extends React.Component { 
  ... 
  async scanDocument() {
    const config: DocumentScannerConfiguration = {
      multiPageEnabled: false,
      ignoreBadAspectRatio: true,
    };
    const result = await ScanbotSDK.UI.startDocumentScanner(config);
    if (result.status === 'OK') {
      this.imageFileUri = result.pages[0].documentPreviewImageFileUri;
      this.forceUpdate();
    }
  }
  ...
}

Now add a <Button> and bind our scanDocument() method to a onPress event:

<SafeAreaView>
  <View style={{padding: 30}}>
    <Button 
        title={'Scan Document'}
        onPress={() => {this.scanDocument();}}
    />
  </View>
</SafeAreaView>

The resulting images are returned as an array of Page elements.

For simplicity, in this example, we have disabled the multipage feature of the Document Scanner via the config parameter multiPageEnabled: false. This means that the Scanner UI will automatically close after a single scan, and we can use the first Page element from the array – result.pages[0] – to display its cropped document image.

With the DocumentScannerConfiguration, you can pass further config parameters to customize colors, text resources, and the behavior of some features of the Document Scanner. See the API docs for more details.

Display the scanned image

Finally, let’s show a preview of the document scanned. For that, we use the React Native component Image to display the last scanned image. The image source is the imageFileUri of the JPG contained in the Page object. To display the last scanned Page image, we implemented a simple method this.forceUpdate() in our scanDocument()function earlier, which will re-render the component:

render() {
    return (
      <SafeAreaView>
        <View style={{padding: 30}}>
     ...
      <Image 
          source={this.imageFileUri}
          style={{width: '100%', height: '100%', resizeMode: 'contain'}}
      />
    </View>
  </SafeAreaView>
);
}

That’s it! Now run the complete project. The app should be able to scan and display a document image:

Android

$ npx react-native run-android

iOS

$ npx react-native run-ios

If you are experiencing any build issues, please kill the Metro server and try again. The Metro server is started by the react-native command in a separate window.

Complete example projects

To get off to a flying start, check out the following example projects on GitHub:

Scanbot SDK (trial) license key

Please note: The Scanbot SDK will run without a license key for one minute per session! After the trial period has expired, all Scanbot SDK functions as well as the UI components will stop working or may be terminated. 

You can get an unrestricted, no-strings-attached 7-day trial license for free.

As the Scanbot SDK license key is bound to an app identifier (aka. Application ID on Android and Bundle Identifier on iOS), you will have to use the app identifier of this tutorial app (com.my_awesome_react_native_app). Of course, you can also use the ID of your app to get a trial license. Please also note that app IDs are case-sensitive!

To request one license key for an app on both platforms, Android and iOS,  make sure the app IDs are the same.

Where to find the app identifier:

  • For Android, see applicationId in the android/app/build.gradle file.
  • For iOS, see Bundle Identifier in the General settings tab in the Xcode IDE.

💡 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.

Developers, ready to get started?

Adding our free trial to your app is easy. Download the Scanbot SDK now and discover the power of mobile data capture