Navaron Bracke

reimplement toggle torch on MacOS

@@ -59,8 +59,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -59,8 +59,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
59 requestPermission(call, result) 59 requestPermission(call, result)
60 case "start": 60 case "start":
61 start(call, result) 61 start(call, result)
62 - case "torch":  
63 - toggleTorch(call, result) 62 + case "toggleTorch":
  63 + toggleTorch(result)
64 case "setScale": 64 case "setScale":
65 setScale(call, result) 65 setScale(call, result)
66 case "resetScale": 66 case "resetScale":
@@ -288,12 +288,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -288,12 +288,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
288 288
289 // Turn on the torch if requested. 289 // Turn on the torch if requested.
290 if (torch) { 290 if (torch) {
291 - do {  
292 - try self.toggleTorchInternal(.on)  
293 - } catch {  
294 - // If the torch could not be turned on,  
295 - // continue the capture session.  
296 - } 291 + self.turnTorchOn()
297 } 292 }
298 293
299 device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) 294 device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil)
@@ -336,12 +331,12 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -336,12 +331,12 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
336 } 331 }
337 332
338 // TODO: this method should be removed when iOS and MacOS share their implementation. 333 // TODO: this method should be removed when iOS and MacOS share their implementation.
339 - private func toggleTorchInternal(_ torch: AVCaptureDevice.TorchMode) throws { 334 + private func toggleTorchInternal() {
340 guard let device = self.device else { 335 guard let device = self.device else {
341 return 336 return
342 } 337 }
343 338
344 - if (!device.hasTorch || !device.isTorchModeSupported(torch)) { 339 + if (!device.hasTorch) {
345 return 340 return
346 } 341 }
347 342
@@ -351,11 +346,56 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -351,11 +346,56 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
351 } 346 }
352 } 347 }
353 348
354 - if (device.torchMode != torch) { 349 + var newTorchMode: AVCaptureDevice.TorchMode = device.torchMode
  350 +
  351 + switch(device.torchMode) {
  352 + case AVCaptureDevice.TorchMode.auto:
  353 + if #available(macOS 10.15, *) {
  354 + newTorchMode = device.isTorchActive ? AVCaptureDevice.TorchMode.off : AVCaptureDevice.TorchMode.on
  355 + }
  356 + break;
  357 + case AVCaptureDevice.TorchMode.off:
  358 + newTorchMode = AVCaptureDevice.TorchMode.on
  359 + break;
  360 + case AVCaptureDevice.TorchMode.on:
  361 + newTorchMode = AVCaptureDevice.TorchMode.off
  362 + break;
  363 + default:
  364 + return;
  365 + }
  366 +
  367 + if (!device.isTorchModeSupported(newTorchMode) || device.torchMode == newTorchMode) {
  368 + return;
  369 + }
  370 +
  371 + do {
355 try device.lockForConfiguration() 372 try device.lockForConfiguration()
356 - device.torchMode = torch 373 + device.torchMode = newTorchMode
357 device.unlockForConfiguration() 374 device.unlockForConfiguration()
  375 + } catch(_) {}
  376 + }
  377 +
  378 + /// Turn the torch on.
  379 + private func turnTorchOn() {
  380 + guard let device = self.device else {
  381 + return
358 } 382 }
  383 +
  384 + if (!device.hasTorch || !device.isTorchModeSupported(.on) || device.torchMode == .on) {
  385 + return
  386 + }
  387 +
  388 + if #available(macOS 15.0, *) {
  389 + if(!device.isTorchAvailable) {
  390 + return
  391 + }
  392 + }
  393 +
  394 + do {
  395 + try device.lockForConfiguration()
  396 + device.torchMode = .on
  397 + device.unlockForConfiguration()
  398 + } catch(_) {}
359 } 399 }
360 400
361 /// Reset the zoom scale. 401 /// Reset the zoom scale.
@@ -370,15 +410,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, @@ -370,15 +410,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
370 result(nil) 410 result(nil)
371 } 411 }
372 412
373 - private func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {  
374 - let requestedTorchMode: AVCaptureDevice.TorchMode = call.arguments as! Int == 1 ? .on : .off  
375 -  
376 - do {  
377 - try self.toggleTorchInternal(requestedTorchMode) 413 + private func toggleTorch(_ result: @escaping FlutterResult) {
  414 + self.toggleTorchInternal()
378 result(nil) 415 result(nil)
379 - } catch {  
380 - result(FlutterError(code: "MobileScanner", message: error.localizedDescription, details: nil))  
381 - }  
382 } 416 }
383 417
384 // func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { 418 // func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {