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.
Other React Native Vision Camera Frame Processor Plugins
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.6.40'
-
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"] ?? "LICENSE-KEY" 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/tony-xlh/vision-camera-dynamsoft-barcode-reader
Disclaimer:
The wrappers and sample code on Dynamsoft Codepool are community editions, shared as-is and not fully tested. Dynamsoft is happy to provide technical support for users exploring these solutions but makes no guarantees.