Skip to content

Commit

Permalink
Merge remote-tracking branch 'ened/fix/720' into swift-async
Browse files Browse the repository at this point in the history
# Conflicts:
#	example/ios/Podfile
#	ios/Classes/MobileScanner.swift
#	ios/Classes/MobileScannerPlugin.swift
  • Loading branch information
juliansteenbakker committed Dec 12, 2023
2 parents 0086632 + 3baf60b commit e59326b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 41 deletions.
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
9 changes: 6 additions & 3 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -473,6 +473,7 @@
DEVELOPMENT_TEAM = 75Y2P2WSQQ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -583,7 +584,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -632,7 +633,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -655,6 +656,7 @@
DEVELOPMENT_TEAM = 75Y2P2WSQQ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -681,6 +683,7 @@
DEVELOPMENT_TEAM = 75Y2P2WSQQ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
52 changes: 31 additions & 21 deletions ios/Classes/MobileScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
var standardZoomFactor: CGFloat = 1

private var nextScanTime = 0.0

private var imagesCurrentlyBeingProcessed = false

public var timeoutSeconds: Double = 0

init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) {
Expand Down Expand Up @@ -95,15 +95,15 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
latestBuffer = imageBuffer
registry?.textureFrameAvailable(textureId)

let currentTime = Date().timeIntervalSince1970
let eligibleForScan = currentTime > nextScanTime && !imagesCurrentlyBeingProcessed

if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) {

nextScanTime = currentTime + timeoutSeconds
imagesCurrentlyBeingProcessed = true

let ciImage = latestBuffer.image

let image = VisionImage(image: ciImage)
Expand All @@ -115,12 +115,12 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega

scanner.process(image) { [self] barcodes, error in
imagesCurrentlyBeingProcessed = false

if (detectionSpeed == DetectionSpeed.noDuplicates) {
let newScannedBarcodes = barcodes?.compactMap({ barcode in
return barcode.rawValue
}).sorted()

if (error == nil && barcodesString != nil && newScannedBarcodes != nil && barcodesString!.elementsEqual(newScannedBarcodes!)) {
return
} else if (newScannedBarcodes?.isEmpty == false) {
Expand All @@ -134,7 +134,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}

/// Start scanning for barcodes
func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: Bool, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws {
func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: Bool, detectionSpeed: DetectionSpeed) async throws -> MobileScannerStartParameters {
// func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: Bool, detectionSpeed: DetectionSpeed, completion: @escaping (MobileScannerStartParameters) -> ()) throws {
self.detectionSpeed = detectionSpeed
if (device != nil) {
throw MobileScannerError.alreadyStarted
Expand Down Expand Up @@ -213,6 +214,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
captureSession.commitConfiguration()

await withCheckedContinuation { continuation in
backgroundQueue.async {
self.captureSession.startRunning()

Expand All @@ -223,22 +225,29 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
if (torch) {
DispatchQueue.main.async {
do {
try self.toggleTorch(.on)
try self.toggleTorch(torch)
} catch {
// If the torch does not turn on,
// continue with the capture session anyway.
print("Failed to set initial torch state.")
}
}
}

DispatchQueue.main.async {
do {
try self.resetScale()
} catch {
// If the zoom scale could not be reset,
// continue with the capture session anyway.
print("Failed to reset zoom scale")
}
}
}

// if self.device == nil {
// throw MobileScannerError.noCamera
// }

if let device = self.device {
// When querying the dimensions of the camera,
Expand All @@ -247,21 +256,22 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
let dimensions = CMVideoFormatDescriptionGetDimensions(
device.activeFormat.formatDescription)
let hasTorch = device.hasTorch
completion(
MobileScannerStartParameters(

// completion(
return MobileScannerStartParameters(
width: Double(dimensions.height),
height: Double(dimensions.width),
hasTorch: hasTorch,
textureId: self.textureId ?? 0
)
)
return
// )

// return
}

completion(MobileScannerStartParameters())
}

return MobileScannerStartParameters()

// completion(MobileScannerStartParameters())
}

/// Stop scanning for barcodes
Expand Down Expand Up @@ -293,11 +303,11 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
guard let device = self.device else {
return
}

if (!device.hasTorch || !device.isTorchAvailable || !device.isTorchModeSupported(torch)) {
return
}

if (device.torchMode != torch) {
try device.lockForConfiguration()
device.torchMode = torch
Expand Down
33 changes: 17 additions & 16 deletions ios/Classes/MobileScannerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
self.barcodeHandler = barcodeHandler
super.init()
}

public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "dev.steenbakker.mobile_scanner/scanner/method", binaryMessenger: registrar.messenger())
let instance = MobileScannerPlugin(barcodeHandler: BarcodeHandler(registrar: registrar), registry: registrar.textures())
Expand All @@ -77,7 +77,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
case "request":
AVCaptureDevice.requestAccess(for: .video, completionHandler: { result($0) })
case "start":
start(call, result)
Task {
await start(call, result)
}
case "stop":
stop(result)
case "torch":
Expand All @@ -94,9 +96,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
result(FlutterMethodNotImplemented)
}
}

/// Start the mobileScanner.
private func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
/// Parses all parameters and starts the mobileScanner
private func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) async {
let torch: Bool = (call.arguments as! Dictionary<String, Any?>)["torch"] as? Bool ?? false
let facing: Int = (call.arguments as! Dictionary<String, Any?>)["facing"] as? Int ?? 1
let formats: Array<Int> = (call.arguments as! Dictionary<String, Any?>)["formats"] as? Array ?? []
Expand All @@ -120,13 +122,12 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
let detectionSpeed: DetectionSpeed = DetectionSpeed(rawValue: speed)!

do {
try mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch, detectionSpeed: detectionSpeed) { parameters in
DispatchQueue.main.async {
result([
"textureId": parameters.textureId,
"size": ["width": parameters.width, "height": parameters.height],
"torchable": parameters.hasTorch])
}
let parameters = try await mobileScanner.start(barcodeScannerOptions: barcodeOptions, returnImage: returnImage, cameraPosition: position, torch: torch, detectionSpeed: detectionSpeed)
DispatchQueue.main.async {
result([
"textureId": parameters.textureId,
"size": ["width": parameters.width, "height": parameters.height],
"torchable": parameters.hasTorch] as [String : Any])
}
} catch MobileScannerError.alreadyStarted {
result(FlutterError(code: "MobileScanner",
Expand Down Expand Up @@ -248,14 +249,14 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
mobileScanner.analyzeImage(image: uiImage!, position: AVCaptureDevice.Position.back, callback: { [self] barcodes, error in
if error != nil {
barcodeHandler.publishEvent(["name": "error", "message": error?.localizedDescription])

DispatchQueue.main.async {
result(false)
}

return
}

if (barcodes == nil || barcodes!.isEmpty) {
DispatchQueue.main.async {
result(false)
Expand All @@ -264,7 +265,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
let barcodesMap: [Any?] = barcodes!.compactMap { barcode in barcode.data }
let event: [String: Any?] = ["name": "barcode", "data": barcodesMap]
barcodeHandler.publishEvent(event)

DispatchQueue.main.async {
result(true)
}
Expand Down

0 comments on commit e59326b

Please sign in to comment.