Committed by
GitHub
Merge pull request #886 from navaronbracke/fix_ios_torch_crash
fix: Fix ios torch crash
Showing
2 changed files
with
52 additions
and
17 deletions
| @@ -215,26 +215,35 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -215,26 +215,35 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 215 | 215 | ||
| 216 | backgroundQueue.async { | 216 | backgroundQueue.async { |
| 217 | self.captureSession.startRunning() | 217 | self.captureSession.startRunning() |
| 218 | - | ||
| 219 | - // Turn on the flashlight if requested, | ||
| 220 | - // but after the capture session started. | 218 | + |
| 219 | + // After the capture session started, turn on the torch (if requested) | ||
| 220 | + // and reset the zoom scale back to the default. | ||
| 221 | + // Ensure that these adjustments are done on the main DispatchQueue, | ||
| 222 | + // as they interact with the hardware camera. | ||
| 221 | if (torch) { | 223 | if (torch) { |
| 224 | + DispatchQueue.main.async { | ||
| 225 | + do { | ||
| 226 | + try self.toggleTorch(.on) | ||
| 227 | + } catch { | ||
| 228 | + // If the torch does not turn on, | ||
| 229 | + // continue with the capture session anyway. | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + DispatchQueue.main.async { | ||
| 222 | do { | 235 | do { |
| 223 | - try self.toggleTorch(.on) | 236 | + try self.resetScale() |
| 224 | } catch { | 237 | } catch { |
| 225 | - // If the torch does not turn on, | 238 | + // If the zoom scale could not be reset, |
| 226 | // continue with the capture session anyway. | 239 | // continue with the capture session anyway. |
| 227 | } | 240 | } |
| 228 | } | 241 | } |
| 229 | 242 | ||
| 230 | - do { | ||
| 231 | - try self.resetScale() | ||
| 232 | - } catch { | ||
| 233 | - // If the zoom scale could not be reset, | ||
| 234 | - // continue with the capture session anyway. | ||
| 235 | - } | ||
| 236 | - | ||
| 237 | if let device = self.device { | 243 | if let device = self.device { |
| 244 | + // When querying the dimensions of the camera, | ||
| 245 | + // stay on the background thread, | ||
| 246 | + // as this does not change the configuration of the hardware camera. | ||
| 238 | let dimensions = CMVideoFormatDescriptionGetDimensions( | 247 | let dimensions = CMVideoFormatDescriptionGetDimensions( |
| 239 | device.activeFormat.formatDescription) | 248 | device.activeFormat.formatDescription) |
| 240 | let hasTorch = device.hasTorch | 249 | let hasTorch = device.hasTorch |
| @@ -277,12 +286,18 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -277,12 +286,18 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 277 | device = nil | 286 | device = nil |
| 278 | } | 287 | } |
| 279 | 288 | ||
| 280 | - /// Toggle the flashlight between on and off. | 289 | + /// Set the torch mode. |
| 290 | + /// | ||
| 291 | + /// This method should be called on the main DispatchQueue. | ||
| 281 | func toggleTorch(_ torch: AVCaptureDevice.TorchMode) throws { | 292 | func toggleTorch(_ torch: AVCaptureDevice.TorchMode) throws { |
| 282 | - if (device == nil || !device.hasTorch || !device.isTorchAvailable) { | 293 | + guard let device = self.device else { |
| 283 | return | 294 | return |
| 284 | } | 295 | } |
| 285 | - | 296 | + |
| 297 | + if (!device.hasTorch || !device.isTorchAvailable || !device.isTorchModeSupported(torch)) { | ||
| 298 | + return | ||
| 299 | + } | ||
| 300 | + | ||
| 286 | if (device.torchMode != torch) { | 301 | if (device.torchMode != torch) { |
| 287 | try device.lockForConfiguration() | 302 | try device.lockForConfiguration() |
| 288 | device.torchMode = torch | 303 | device.torchMode = torch |
| @@ -61,6 +61,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -61,6 +61,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 61 | start(call, result) | 61 | start(call, result) |
| 62 | case "torch": | 62 | case "torch": |
| 63 | toggleTorch(call, result) | 63 | toggleTorch(call, result) |
| 64 | + case "setScale": | ||
| 65 | + setScale(call, result) | ||
| 66 | + case "resetScale": | ||
| 67 | + resetScale(call, result) | ||
| 64 | // case "analyze": | 68 | // case "analyze": |
| 65 | // switchAnalyzeMode(call, result) | 69 | // switchAnalyzeMode(call, result) |
| 66 | case "stop": | 70 | case "stop": |
| @@ -320,7 +324,11 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -320,7 +324,11 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 320 | 324 | ||
| 321 | // TODO: this method should be removed when iOS and MacOS share their implementation. | 325 | // TODO: this method should be removed when iOS and MacOS share their implementation. |
| 322 | private func toggleTorchInternal(_ torch: AVCaptureDevice.TorchMode) throws { | 326 | private func toggleTorchInternal(_ torch: AVCaptureDevice.TorchMode) throws { |
| 323 | - if (device == nil || !device.hasTorch) { | 327 | + guard let device = self.device else { |
| 328 | + return | ||
| 329 | + } | ||
| 330 | + | ||
| 331 | + if (!device.hasTorch || !device.isTorchModeSupported(torch)) { | ||
| 324 | return | 332 | return |
| 325 | } | 333 | } |
| 326 | 334 | ||
| @@ -337,7 +345,19 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -337,7 +345,19 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 337 | } | 345 | } |
| 338 | } | 346 | } |
| 339 | 347 | ||
| 340 | - func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 348 | + /// Reset the zoom scale. |
| 349 | + private func resetScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 350 | + // The zoom scale is not yet supported on MacOS. | ||
| 351 | + result(nil) | ||
| 352 | + } | ||
| 353 | + | ||
| 354 | + /// Set the zoom scale. | ||
| 355 | + private func setScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 356 | + // The zoom scale is not yet supported on MacOS. | ||
| 357 | + result(nil) | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + private func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 341 | let requestedTorchMode: AVCaptureDevice.TorchMode = call.arguments as! Int == 1 ? .on : .off | 361 | let requestedTorchMode: AVCaptureDevice.TorchMode = call.arguments as! Int == 1 ? .on : .off |
| 342 | 362 | ||
| 343 | do { | 363 | do { |
-
Please register or login to post a comment