How to Build a Cross-Platform QR Code Scanner with Capacitor
Capacitor is an open source native runtime created by the Ionic team for building Web Native apps. We can use it to create cross-platform iOS, Android, and Progressive Web Apps with JavaScript, HTML, and CSS.1 As an alternative to Cordova, Capacitor delivers the same cross-platform benefits, but with a more modern approach to app development, taking advantage of the latest Web APIs and native platform capabilities.2
In this article, we are going to talk about how to use the capacitor barcode reader plugin to build a QR code scanner using Dynamsoft Barcode Reader (DBR) along with Dynamsoft Camera Enhancer (DCE).
Getting started with Dynamsoft Barcode Reader
DOWNLOAD THE SDK WITH A 30-DAY LICENSE
REQUEST A 30-DAY LICENSE
Build a QR Code Scanner using Capacitor
Integrate Capacitor with an Existing Web App
Capacitor can be integrated with existing web apps to add native functionality.
Here, we create a webpack app with a template first.
git clone https://github.com/wbkd/webpack-starter
Then, drop Capacitor into the project.
cd webpack-starter
npm install @capacitor/cli @capacitor/core
npx cap init
Then, we can create projects for Android and iOS.
npm install @capacitor/ios @capacitor/android
npx cap add ios
npx cap add android
Use the following commands to update files after the app is changed:
npm run build
npx cap sync
Use the following commands to start the app:
npm run start // run in browsers
npx cap run android // run on Android devices
npx cap run ios // run on iOS devices
Use Plugins to Bring QR Code Scanning Functionality to the App
Plugins in Capacitor enable JavaScript to interface directly with Native APIs.3 A plugin has been created to make it easy to use Dynamsoft Barcode Reader and Dynamsoft Camera Enhancer in a Capacitor app to scan QR codes. Since Dynamsoft Barcode Reader has Android, iOS and JavaScript editions, the plugin also supports Android, iOS and Web. We can test the app on the web browsers first and then make modifications to make it compatible with native platforms.
-
Install the plugin to the web app we just create.
npm install capacitor-plugin-dynamsoft-barcode-reader
-
Add a
start scanning
button, a camera select and a result container in acontrols
container. In addition, a statusspan
is added as well to show whether Dynamsoft Barcode Reader has been initialized.<span id="status">Initializing...</span> <div id="controls" style="display:none;"> <select id="cameraSelect" style="max-width:200px;"></select> <button id="controlButton">Start Scanning</button> <div id="result"></div> </div>
-
Initialize the plugin when the page is loaded. You may need to apply for a trial license to use DBR from here.
import { DBR } from 'capacitor-plugin-dynamsoft-barcode-reader'; initDBR(); async function initDBR(){ let options = {license:"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="}; let result = await DBR.initialize(options); if (result) { if (result.success == true) { await loadCameras(); document.getElementById("status").remove(); document.getElementById("controls").style.display = ""; DBR.addListener('onFrameRead', (retObj) => { onFrameRead(retObj); }); } } }
If the initialization is successful, it will load cameras to the camera select, hide the initializing span, reveal the controls and add a listener to get the barcode results.
The
loadCameras
function:async function loadCameras(){ let cameraSelect = document.getElementById("cameraSelect"); let result = await DBR.getAllCameras(); result.cameras.forEach(camera => { let option = document.createElement("option"); option.value = camera; option.label = camera; cameraSelect.appendChild(option); }); }
-
Add the
onclick
event for thestart scanning
button.function toggleScan(){ if (document.getElementById("controlButton").innerText == "Stop Scanning") { stopScan(); }else{ startScan(); } }
If the scanner is opened, then stop scan, otherwise, start scan.
The
startScan
and thestopScan
functions:async function startScan(){ scanned = false; document.getElementById("result").innerHTML = ""; await onCameraSelectionChanged(); await DBR.startScan(); document.body.style.background = "transparent"; document.getElementById("controls").className = "fullscreen"; document.getElementById("controlButton").innerText = "Stop Scanning"; } async function stopScan(){ document.getElementById("controls").className = ""; await DBR.stopScan(); document.body.style.background = "white"; document.getElementById("controlButton").innerText = "Start Scanning"; }
Please note that the plugin puts the camera preview under the webview on Android and iOS. We need to set the background to transparent to reveal the camera.
-
When barcodes are found, stop scanning and display the results.
function onFrameRead(retObj){ let results = retObj["results"]; if (results.length>0 && scanned == false) { scanned = true; let ol = document.createElement("ol"); for (let index = 0; index < results.length; index++) { let li = document.createElement("li"); const result = results[index]; li.innerText = result["barcodeFormat"]+": "+result["barcodeText"]; ol.appendChild(li); } stopScan(); document.getElementById("result").innerHTML = ol.outerHTML; } }
Add Camera Permissions for iOS
We have to configure the camera permission for iOS in order to use the camera.
Add the following to Info.plist
:
<key>NSCameraUsageDescription</key>
<string>For barcode scanning</string>
Ionic React Example
You can learn about how to use the plugin in React in a declarative way by checking out this article: Ionic React QR Code Scanner with Capacitor.
Source Code
https://github.com/xulihang/capacitor-qr-code-scanner