React Native ISBN Scanner

The International Standard Book Number (ISBN) is a numeric commercial book identifier. We can find it on the back cover of a book. An EAN-13 barcode is usually printed to be read by machines.

In this article, we are going to build a React Native app to scan ISBN using Dynamsoft Barcode Reader and get its info using the Google Book API.

Demo video:

Prerequisites

Get your trial key.

Request a Trial License

Demo: DLS2eyJvcmdhbml6YXeyJo34567AwMDAxLTEwM34XphdGlvbk812345AxIn0=
Reveal

This generates an online license that collects data regarding your usage of the SDK. If you prefer an offline license key, please contact us.​

Your Trial License

DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTEwMTIwMDkzNiIsIm9yZ2FuaXphdGlvbklEIjoiMjAwMDAxIn0=
Copy
Copied!

Request a Trial License - Successful

The license will be sent to your email immediately. If you don't see it in your inbox, please check your junk/spam folder as well.

New React Native Project

Create a new React Native project with a specific version:

npx @react-native-community/cli init ISBNScanner --version 0.75.2

Add Dynamsoft Barcode Reader

Install the Dynamsoft Capture Vision package which has Dynamsoft Barcode Reader included:

npm install dynamsoft-capture-vision-react-native

Set the License

Set the license in App.tsx when the app starts.

useEffect(()=>{
  LicenseManager.initLicense('LICENSE-KEY')
  .then(()=>{/*Init license successfully.*/})
  .catch(error => console.error('Init License failed.', error));
},[]);

Request Camera Permission

  1. Declare the camera usage for iOS by adding the following lines to Info.plist.

    <key>NSCameraUsageDescription</key>
    <string>For barcode scanning</string>
    
  2. When the app starts, request camera permission.

    useEffect(()=>{
      CameraEnhancer.requestCameraPermission();
    },[]);
    

Create an ISBN Scanning Component

  1. Create a new file under components/BarcodeScanner.tsx with the following template:

    import React, {useEffect, useRef} from 'react';
    import {DecodedBarcodesResult} from 'dynamsoft-capture-vision-react-native';
    import { StyleSheet } from 'react-native';
    
    export interface ScannerProps{
      onScanned?: (result:DecodedBarcodesResult) => void;
    }
    
    export function BarcodeScanner(props:ScannerProps) {
      return (
        <></>
      );
    }
    const styles = StyleSheet.create({
      container: {
        flex:1,
      },
    });
    
  2. Add a CameraView component.

    export function BarcodeScanner(props:ScannerProps) {
       const cameraView = useRef<CameraView>(null);
       return (
         <CameraView style={styles.container} ref={cameraView} />
       );
    }
    
  3. Get the instance of Camera to open the camera and display the camera preview in the CameraView component.

    export function BarcodeScanner(props:ScannerProps) {
      const cameraView = useRef<CameraView>(null);
      const camera = CameraEnhancer.getInstance();
      useEffect(() => {
        camera.setCameraView(cameraView.current!!);
        camera.open();
        return () => {
          //close the camera when the component is going to be unmounted
          camera.close();
        };
      }, [camera, cameraView, props]);
    
      return (
        <CameraView style={styles.container} ref={cameraView} />
      );
    }
    
  4. Get the instance of Capture Vision Router to call the Barcode Reader to read the barcodes from the camera frames.

    export function BarcodeScanner(props:ScannerProps) {
      const router = CaptureVisionRouter.getInstance();
      useEffect(() => {
        //...
        router.initSettings(dotcodeTemplate);
        router.setInput(camera);
        let resultReceiver = router.addResultReceiver({
          onDecodedBarcodesReceived: (result: DecodedBarcodesResult) =>  {
            console.log('scanned');
            if (props.onScanned) {
              props.onScanned(result);
            }
          },
        });
           
        router.startCapturing(EnumPresetTemplate.PT_READ_SINGLE_BARCODE);
           
        return () => {
          //...
          router.removeResultReceiver(resultReceiver!);
        };
      }, [camera, router, cameraView, props]);
    }
    
  5. Specify the barcode format to EAN-13 so that it will not read other barcode formats.

    let settings: SimplifiedCaptureVisionSettings = {
      barcodeSettings: {
        barcodeFormatIds:  EnumBarcodeFormat.BF_EAN_13,
      }
    };
    await router.updateSettings(settings,EnumPresetTemplate.PT_READ_SINGLE_BARCODE);
    

Use the ISBN Scanner Component

Update App.tsx to use the ISBN scanner component to scan an ISBN and display the result.

import React, { useEffect } from 'react';
import {
  Button,
  SafeAreaView,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { BarcodeScanner } from './components/BarcodeScanner';
import { CameraEnhancer, DecodedBarcodesResult, LicenseManager } from 'dynamsoft-capture-vision-react-native';

function App(): React.JSX.Element {
  const [isScanning, setIsScanning] = React.useState(false);
  const [barcodeText, setBarcodeText] = React.useState('');
  useEffect(()=>{
    LicenseManager.initLicense('LICENSE-KEY')
    .then(()=>{/*Init license successfully.*/})
    .catch(error => console.error('Init License failed.', error));
    CameraEnhancer.requestCameraPermission();
  },[]);

  const toggleScanning = () => {
    setIsScanning(!isScanning);
  };

  const onScanned = (result:DecodedBarcodesResult) => {
    if (result.items && result.items.length > 0) {
      console.log(result.items[0].text);
      toggleScanning();
      setBarcodeText(result.items[0].text);
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      {isScanning &&
      <>
        <BarcodeScanner
          onScanned={onScanned}
        />
        <View style={styles.controls}>
          <Button title="Stop Scanning" onPress={toggleScanning}/>
        </View>
      </>}
      {!isScanning &&
        <View style={styles.home}>
          <Text>DotCode Scanner</Text>
          <Button title="Start Scanning" onPress={toggleScanning}/>
          {barcodeText &&
            <Text>{'Result: ' + barcodeText}</Text>
          }
        </View>
      }
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex:1,
  },
  home:{
    alignItems:'center',
  },
  controls:{
    position:'absolute',
    width:'100%',
    alignItems:'center',
    bottom:10,
  },
  button:{
    width: '50%',
  },
});

export default App;

Get the Book Info via the Google Book API

We can take a step further to retrieve the book info like its author, title, publisher and cover image.

const response = await fetch(
  'https://www.googleapis.com/books/v1/volumes?q=isbn:'+ISBN,
);
const json = await response.json();
const bookItem = json.items[0];
const title = bookItem.volumeInfo.title;
const publisher = bookItem.volumeInfo.publisher;
const authors = bookItem.volumeInfo.authors.join(",");
const imageLink = bookItem.volumeInfo.imageLinks.thumbnail;

Source Code

Check out the source code to have a try:

https://github.com/tony-xlh/react-native-isbn-scanner