Julian Steenbakker
Committed by GitHub

Merge pull request #667 from ened/fix/ios-threading

fix: Start running the capture session on a background thread
@@ -51,6 +51,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -51,6 +51,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
51 51
52 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates 52 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates
53 53
  54 + private let backgroundQueue = DispatchQueue(label: "camera-handling")
  55 +
54 var standardZoomFactor: CGFloat = 1 56 var standardZoomFactor: CGFloat = 1
55 57
56 init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) { 58 init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) {
@@ -118,7 +120,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -118,7 +120,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
118 } 120 }
119 121
120 /// Start scanning for barcodes 122 /// Start scanning for barcodes
121 - func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: AVCaptureDevice.TorchMode, detectionSpeed: DetectionSpeed) throws -> MobileScannerStartParameters { 123 + func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: AVCaptureDevice.TorchMode, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws {
122 self.detectionSpeed = detectionSpeed 124 self.detectionSpeed = detectionSpeed
123 if (device != nil) { 125 if (device != nil) {
124 throw MobileScannerError.alreadyStarted 126 throw MobileScannerError.alreadyStarted
@@ -195,24 +197,36 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -195,24 +197,36 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
195 } 197 }
196 } 198 }
197 captureSession.commitConfiguration() 199 captureSession.commitConfiguration()
198 - captureSession.startRunning()  
199 - // Enable the torch if parameter is set and torch is available  
200 - // torch should be set after 'startRunning' is called  
201 - do {  
202 - try toggleTorch(torch)  
203 - } catch {  
204 - print("Failed to set initial torch state.")  
205 - }  
206 200
207 - do {  
208 - try resetScale()  
209 - } catch {  
210 - print("Failed to reset zoom scale")  
211 - } 201 + backgroundQueue.async {
  202 + self.captureSession.startRunning()
  203 + // Enable the torch if parameter is set and torch is available
  204 + // torch should be set after 'startRunning' is called
  205 + do {
  206 + try self.toggleTorch(torch)
  207 + } catch {
  208 + print("Failed to set initial torch state.")
  209 + }
212 210
213 - let dimensions = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription) 211 + do {
  212 + try self.resetScale()
  213 + } catch {
  214 + print("Failed to reset zoom scale")
  215 + }
214 216
215 - return MobileScannerStartParameters(width: Double(dimensions.height), height: Double(dimensions.width), hasTorch: device.hasTorch, textureId: textureId) 217 + let dimensions = CMVideoFormatDescriptionGetDimensions(self.device.activeFormat.formatDescription)
  218 +
  219 + DispatchQueue.main.async {
  220 + completion(
  221 + MobileScannerStartParameters(
  222 + width: Double(dimensions.height),
  223 + height: Double(dimensions.width),
  224 + hasTorch: self.device.hasTorch,
  225 + textureId: self.textureId
  226 + )
  227 + )
  228 + }
  229 + }
216 } 230 }
217 231
218 /// Stop scanning for barcodes 232 /// Stop scanning for barcodes
@@ -120,8 +120,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { @@ -120,8 +120,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin {
120 let detectionSpeed: DetectionSpeed = DetectionSpeed(rawValue: speed)! 120 let detectionSpeed: DetectionSpeed = DetectionSpeed(rawValue: speed)!
121 121
122 do { 122 do {
123 - let parameters = try mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch ? .on : .off, detectionSpeed: detectionSpeed)  
124 - result(["textureId": parameters.textureId, "size": ["width": parameters.width, "height": parameters.height], "torchable": parameters.hasTorch]) 123 + try mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch ? .on : .off, detectionSpeed: detectionSpeed) { parameters in
  124 + result(["textureId": parameters.textureId, "size": ["width": parameters.width, "height": parameters.height], "torchable": parameters.hasTorch])
  125 + }
125 } catch MobileScannerError.alreadyStarted { 126 } catch MobileScannerError.alreadyStarted {
126 result(FlutterError(code: "MobileScanner", 127 result(FlutterError(code: "MobileScanner",
127 message: "Called start() while already started!", 128 message: "Called start() while already started!",