From 3baf60b2ab6ba09c91029ae62677dc20a63c0562 Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Wed, 9 Aug 2023 07:55:54 +0100 Subject: [PATCH] Switch to iOS 13, use Tasks to handle threads and add error handling for nil --- example/ios/Podfile | 4 +- example/ios/Runner.xcodeproj/project.pbxproj | 9 ++- ios/Classes/MobileScanner.swift | 61 +++++++++++--------- ios/Classes/SwiftMobileScannerPlugin.swift | 19 ++++-- 4 files changed, 55 insertions(+), 38 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 266f93e66..592f30407 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -39,7 +39,7 @@ post_install do |installer| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['ENABLE_BITCODE'] = 'NO' - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' end end end diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 72ce5badc..2a2d05bdf 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -342,7 +342,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; @@ -363,6 +363,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", @@ -423,7 +424,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; @@ -472,7 +473,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; @@ -495,6 +496,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", @@ -521,6 +523,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", diff --git a/ios/Classes/MobileScanner.swift b/ios/Classes/MobileScanner.swift index bee7adfce..b85d54c2d 100644 --- a/ios/Classes/MobileScanner.swift +++ b/ios/Classes/MobileScanner.swift @@ -120,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, completion: @escaping (MobileScannerStartParameters) -> ()) throws { + func start(barcodeScannerOptions: BarcodeScannerOptions?, returnImage: Bool, cameraPosition: AVCaptureDevice.Position, torch: AVCaptureDevice.TorchMode, detectionSpeed: DetectionSpeed) async throws -> MobileScannerStartParameters { self.detectionSpeed = detectionSpeed if (device != nil) { throw MobileScannerError.alreadyStarted @@ -197,36 +197,41 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega } } captureSession.commitConfiguration() + + await withCheckedContinuation { continuation in + 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.") + } - 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.") - } - - do { - try self.resetScale() - } catch { - print("Failed to reset zoom scale") - } - - 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 - ) - ) + do { + try self.resetScale() + } catch { + print("Failed to reset zoom scale") + } + + continuation.resume() } } + + let dimensions = CMVideoFormatDescriptionGetDimensions(self.device.activeFormat.formatDescription) + + if self.device == nil { + throw MobileScannerError.noCamera + } + + return MobileScannerStartParameters( + width: Double(dimensions.height), + height: Double(dimensions.width), + hasTorch: self.device.hasTorch, + textureId: self.textureId + ) } /// Stop scanning for barcodes diff --git a/ios/Classes/SwiftMobileScannerPlugin.swift b/ios/Classes/SwiftMobileScannerPlugin.swift index 232b14532..8fdb1f49e 100644 --- a/ios/Classes/SwiftMobileScannerPlugin.swift +++ b/ios/Classes/SwiftMobileScannerPlugin.swift @@ -78,7 +78,9 @@ public class SwiftMobileScannerPlugin: 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": @@ -97,7 +99,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { } /// Parses all parameters and starts the mobileScanner - private func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { + private func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) async { let torch: Bool = (call.arguments as! Dictionary)["torch"] as? Bool ?? false let facing: Int = (call.arguments as! Dictionary)["facing"] as? Int ?? 1 let formats: Array = (call.arguments as! Dictionary)["formats"] as? Array ?? [] @@ -120,9 +122,16 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { let detectionSpeed: DetectionSpeed = DetectionSpeed(rawValue: speed)! do { - 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]) - } + let parameters = try await 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 + ] as [String : Any]) } catch MobileScannerError.alreadyStarted { result(FlutterError(code: "MobileScanner", message: "Called start() while already started!",