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
var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates
private let backgroundQueue = DispatchQueue(label: "camera-handling")
var standardZoomFactor: CGFloat = 1
init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) {
... ... @@ -118,7 +120,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
/// Start scanning for barcodes
func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: AVCaptureDevice.TorchMode, detectionSpeed: DetectionSpeed) throws -> MobileScannerStartParameters {
func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: AVCaptureDevice.TorchMode, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws {
self.detectionSpeed = detectionSpeed
if (device != nil) {
throw MobileScannerError.alreadyStarted
... ... @@ -195,24 +197,36 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
}
captureSession.commitConfiguration()
captureSession.startRunning()
// Enable the torch if parameter is set and torch is available
// torch should be set after 'startRunning' is called
do {
try toggleTorch(torch)
} catch {
print("Failed to set initial torch state.")
}
do {
try resetScale()
} catch {
print("Failed to reset zoom scale")
}
backgroundQueue.async {
self.captureSession.startRunning()
// Enable the torch if parameter is set and torch is available
// torch should be set after 'startRunning' is called
do {
try self.toggleTorch(torch)
} catch {
print("Failed to set initial torch state.")
}
let dimensions = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription)
do {
try self.resetScale()
} catch {
print("Failed to reset zoom scale")
}
return MobileScannerStartParameters(width: Double(dimensions.height), height: Double(dimensions.width), hasTorch: device.hasTorch, textureId: textureId)
let dimensions = CMVideoFormatDescriptionGetDimensions(self.device.activeFormat.formatDescription)
DispatchQueue.main.async {
completion(
MobileScannerStartParameters(
width: Double(dimensions.height),
height: Double(dimensions.width),
hasTorch: self.device.hasTorch,
textureId: self.textureId
)
)
}
}
}
/// Stop scanning for barcodes
... ...
... ... @@ -120,8 +120,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin {
let detectionSpeed: DetectionSpeed = DetectionSpeed(rawValue: speed)!
do {
let parameters = try mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch ? .on : .off, detectionSpeed: detectionSpeed)
result(["textureId": parameters.textureId, "size": ["width": parameters.width, "height": parameters.height], "torchable": parameters.hasTorch])
try mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch ? .on : .off, detectionSpeed: detectionSpeed) { parameters in
result(["textureId": parameters.textureId, "size": ["width": parameters.width, "height": parameters.height], "torchable": parameters.hasTorch])
}
} catch MobileScannerError.alreadyStarted {
result(FlutterError(code: "MobileScanner",
message: "Called start() while already started!",
... ...