Build a React Native Vision Camera Frame Processor Plugin to Scan Barcodes for iOS
In the previous article, we’ve created a React Native Vision Camera frame processor plugin for Dynamsoft Barcode Reader (DBR). Let’s continue to create the frame processor plugin for iOS.
This article is Part 2 in a 3-Part Series.
PS: If you don’t need to use Vision Camera, you can use the Dynamsoft Capture Vision package instead to scan barcodes.
Getting started with Dynamsoft Barcode Reader
DOWNLOAD THE SDK WITH A 30-DAY LICENSE
REQUEST A 30-DAY LICENSE
Building the React Native Vision Camera Frame Processor Plugin of Barcode Reader for iOS
Let’s do this in steps.
Implement the iOS Part of the Plugin
-
Add Dynamsoft Barcode Reader to
vision-camera-dynamsoft-barcode-reader.podspec
s.libraries = 'c++' s.dependency 'DynamsoftBarcodeReader', '= 9.0.0'
-
Go to
ios
, removeVisionCameraDynamsoftBarcodeReader.swift
andVisionCameraDynamsoftBarcodeReader.m
-
Create a new file named
VisionCameraDBRPlugin.swift
with the following content:import Foundation @objc(VisionCameraDBRPlugin) public class VisionCameraDBRPlugin: NSObject, FrameProcessorPluginBase { @objc public static func callback(_ frame: Frame!, withArgs args: [Any]!) -> Any! { // code goes here return [] } }
-
Add the following content to
VisionCameraDynamsoftBarcodeReader-Bridging-Header.h
#import <VisionCamera/FrameProcessorPlugin.h> #import <VisionCamera/Frame.h>
-
Create a new Objective-C file with the same name as the Swift file with the following content:
#import <Foundation/Foundation.h> #import <VisionCamera/FrameProcessorPlugin.h> @interface VISION_EXPORT_SWIFT_FRAME_PROCESSOR(decode, VisionCameraDBRPlugin) @end
-
Create a new
BarcodeReaderInitializer.swift
to initialize Dynamsoft Barcode Reader:public class BarcodeReaderInitializer: NSObject, DBRLicenseVerificationListener { func configurationDBR(license:String) -> DynamsoftBarcodeReader { var dbr:DynamsoftBarcodeReader DynamsoftBarcodeReader.initLicense(license, verificationDelegate: self) dbr = DynamsoftBarcodeReader.init() return dbr } public func dbrLicenseVerificationCallback(_ isSuccess: Bool, error: Error?) { let err = error as NSError? if(err != nil){ print("Server DBR license verify failed") } } }
-
Use the
Initializer
to create an instance of Dynamsoft Barcode Reader if the plugin is called:private static var barcodeReader:DynamsoftBarcodeReader! = nil public static func callback(_ frame: Frame!, withArgs args: [Any]!) -> Any! { let config = getConfig(withArgs: args) if barcodeReader == nil { initDBR(config: config) } return [] } static func initDBR(config: [String:String]!) { var license = ""; license = config?["license"] ?? "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==" let initializer = BarcodeReaderInitializer(); barcodeReader = initializer.configurationDBR(license: license) } static func getConfig(withArgs args: [Any]!) -> [String:String]!{ if args.count>0 { let config = args[0] as? [String: String] return config } return nil }
-
Decode the image using Dynamsoft Barcode Reader and return the result
private static let context = CIContext(options: nil) @objc public static func callback(_ frame: Frame!, withArgs args: [Any]!) -> Any! { let config = getConfig(withArgs: args) if barcodeReader == nil { initDBR(config: config) } guard let imageBuffer = CMSampleBufferGetImageBuffer(frame.buffer) else { print("Failed to get CVPixelBuffer!") return nil } let ciImage = CIImage(cvPixelBuffer: imageBuffer) guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { print("Failed to create CGImage!") return nil } var returned_results: [Any] = [] let image = UIImage(cgImage: cgImage) // code goes here let results = try? barcodeReader.decodeImage(image) let count = results?.count ?? 0 if count > 0 { for index in 0..<count { let tr = results![index] returned_results.append(wrapResult(result: tr)) } print("Found barcodes") } return returned_results } static func wrapResult(result: iTextResult) -> Any { var map: [String: Any] = [:] map["barcodeText"] = result.barcodeText map["barcodeFormat"] = result.barcodeFormatString let points = result.localizationResult?.resultPoints as! [CGPoint] map["x1"] = points[0].x map["x2"] = points[1].x map["x3"] = points[2].x map["x4"] = points[3].x map["y1"] = points[0].y map["y2"] = points[1].y map["y3"] = points[2].y map["y4"] = points[3].y return map }
The iOS implementation of the React Native Vision Camera plugin is now completed.
We can do the following to test the example project.
-
Add camera permission to the example project by adding the following to
Info.plist
.<key>NSCameraUsageDescription</key> <string>For barcode scanning</string>
-
Run the following to install pods.
cd example/ios pod install
-
Run the project for iOS.
npx react-native run-ios
Source Code
You can check out the source code for more details.
https://github.com/xulihang/vision-camera-dynamsoft-barcode-reader