From bb1a328cc325ecf2d43dbcf1c2fa088475dc0685 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Mon, 16 Oct 2023 13:24:22 +0200 Subject: [PATCH 1/2] port scan timeout to iOS --- ios/Classes/MobileScanner.swift | 25 ++++++++++++++++------ ios/Classes/SwiftMobileScannerPlugin.swift | 9 +++++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/ios/Classes/MobileScanner.swift b/ios/Classes/MobileScanner.swift index 37aa8770e..3cde01422 100644 --- a/ios/Classes/MobileScanner.swift +++ b/ios/Classes/MobileScanner.swift @@ -54,6 +54,12 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega private let backgroundQueue = DispatchQueue(label: "camera-handling") var standardZoomFactor: CGFloat = 1 + + private var nextScanTime = 0.0 + + private var imagesCurrentlyBeingProcessed = 0 + + public var timeoutSeconds: Double = 0 init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) { self.registry = registry @@ -89,8 +95,15 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega } latestBuffer = imageBuffer registry?.textureFrameAvailable(textureId) - if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && i > 10 || detectionSpeed == DetectionSpeed.unrestricted) { - i = 0 + + let currentTime = Date().timeIntervalSince1970 + let eligibleForScan = currentTime > nextScanTime && imagesCurrentlyBeingProcessed == 0 + + if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) { + + nextScanTime = currentTime + timeoutSeconds + imagesCurrentlyBeingProcessed += 1 + let ciImage = latestBuffer.image let image = VisionImage(image: ciImage) @@ -101,6 +114,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega ) scanner.process(image) { [self] barcodes, error in + imagesCurrentlyBeingProcessed -= 1 + if (detectionSpeed == DetectionSpeed.noDuplicates) { let newScannedBarcodes = barcodes?.map { barcode in return barcode.rawValue @@ -114,8 +129,6 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega mobileScannerCallback(barcodes, error, ciImage) } - } else { - i+=1 } } @@ -301,7 +314,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega do { try device.lockForConfiguration() - var maxZoomFactor = device.activeFormat.videoMaxZoomFactor + let maxZoomFactor = device.activeFormat.videoMaxZoomFactor var actualScale = (scale * 4) + 1 @@ -348,8 +361,6 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega scanner.process(image, completion: callback) } - var i = 0 - var barcodesString: Array? diff --git a/ios/Classes/SwiftMobileScannerPlugin.swift b/ios/Classes/SwiftMobileScannerPlugin.swift index 232b14532..0f15cfda3 100644 --- a/ios/Classes/SwiftMobileScannerPlugin.swift +++ b/ios/Classes/SwiftMobileScannerPlugin.swift @@ -12,8 +12,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { /// The handler sends all information via an event channel back to Flutter private let barcodeHandler: BarcodeHandler + /// The points for the scan window. static var scanWindow: [CGFloat]? - + private static func isBarcodeInScanWindow(barcode: Barcode, imageSize: CGSize) -> Bool { let scanwindow = SwiftMobileScannerPlugin.scanWindow! let barcodeminX = barcode.cornerPoints![0].cgPointValue.x @@ -103,7 +104,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { let formats: Array = (call.arguments as! Dictionary)["formats"] as? Array ?? [] let returnImage: Bool = (call.arguments as! Dictionary)["returnImage"] as? Bool ?? false let speed: Int = (call.arguments as! Dictionary)["speed"] as? Int ?? 0 - + let timeoutMs: Int = (call.arguments as! Dictionary)["timeout"] as? Int ?? 0 + self.mobileScanner.timeoutSeconds = Double(timeoutMs / 1000) + let formatList = formats.map { format in return BarcodeFormat(rawValue: format)} var barcodeOptions: BarcodeScannerOptions? = nil @@ -168,7 +171,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { /// Toggles the zoomScale private func setScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { - var scale = call.arguments as? CGFloat + let scale = call.arguments as? CGFloat if (scale == nil) { result(FlutterError(code: "MobileScanner", message: "You must provide a scale when calling setScale!", From f884acb16a01775339356af3a421d732f3569ca2 Mon Sep 17 00:00:00 2001 From: Navaron Bracke Date: Fri, 20 Oct 2023 18:40:23 +0200 Subject: [PATCH 2/2] use a boolean instead of a double --- ios/Classes/MobileScanner.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/Classes/MobileScanner.swift b/ios/Classes/MobileScanner.swift index 3cde01422..40b7cb8fa 100644 --- a/ios/Classes/MobileScanner.swift +++ b/ios/Classes/MobileScanner.swift @@ -57,7 +57,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega private var nextScanTime = 0.0 - private var imagesCurrentlyBeingProcessed = 0 + private var imagesCurrentlyBeingProcessed = false public var timeoutSeconds: Double = 0 @@ -97,12 +97,12 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega registry?.textureFrameAvailable(textureId) let currentTime = Date().timeIntervalSince1970 - let eligibleForScan = currentTime > nextScanTime && imagesCurrentlyBeingProcessed == 0 + let eligibleForScan = currentTime > nextScanTime && !imagesCurrentlyBeingProcessed if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) { nextScanTime = currentTime + timeoutSeconds - imagesCurrentlyBeingProcessed += 1 + imagesCurrentlyBeingProcessed = true let ciImage = latestBuffer.image @@ -114,7 +114,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega ) scanner.process(image) { [self] barcodes, error in - imagesCurrentlyBeingProcessed -= 1 + imagesCurrentlyBeingProcessed = false if (detectionSpeed == DetectionSpeed.noDuplicates) { let newScannedBarcodes = barcodes?.map { barcode in