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.
Links related to Dynamsoft Barcode Reader
Building the React Native Vision Camera Frame Processor Plugin of Barcode Reader for iOS
Import DBR
We need to import the DBR framework first
-
Open
vision-camera-dynamsoft-barcode-reader.podspec
and add the following lines:s.libraries = 'c++' s.dependency 'DynamsoftBarcodeReader', '= 9.0.0'
-
Update pods
cd example/ios pod install
Add Camera Permission
We also need to add the following to Info.plist
for camera permission:
<key>NSCameraUsageDescription</key>
<string>For barcode scanning</string>
<key>NSMicrophoneUsageDescription</key>
<string>For barcode scanning</string>
Implement the iOS Part of the Plugin
-
Go to
ios
, removeVisionCameraDynamsoftBarcodeReader.swift
andVisionCameraDynamsoftBarcodeReader.swift
-
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. You can test the project following the previous article’s guide.
Source Code
You can check out the source code for more details.
https://github.com/xulihang/vision-camera-dynamsoft-barcode-reader