Navaron Bracke
Committed by GitHub

Merge pull request #826 from navaronbracke/fix_platform_messages_threading

fix: Fix platform messages threading
... ... @@ -15,6 +15,7 @@ Bugs fixed:
* Fixed the default values for the `format` and `type` arguments of the Barcode constructor.
These now use `BarcodeFormat.unknown` and `BarcodeType.unknown`, rather than `BarcodeFormat.ean13` and `BarcodeType.text`.
(thanks @navaronbracke !)
* Fixed messages not being sent on the main thread for Android, iOS and MacOS. (thanks @navaronbracke !)
## 3.5.0
New Features:
... ...
... ... @@ -2,6 +2,8 @@ package dev.steenbakker.mobile_scanner
import android.app.Activity
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.util.Size
import androidx.camera.core.CameraSelector
import androidx.camera.core.ExperimentalGetImage
... ... @@ -30,12 +32,13 @@ class MobileScannerHandler(
"name" to "barcode",
"data" to barcodes
))
analyzerResult?.success(true)
} else {
analyzerResult?.success(false)
}
Handler(Looper.getMainLooper()).post {
analyzerResult?.success(barcodes != null)
analyzerResult = null
}
}
private var analyzerResult: MethodChannel.Result? = null
... ... @@ -92,7 +95,6 @@ class MobileScannerHandler(
if(listener != null) {
activityPluginBinding.removeRequestPermissionsResultListener(listener)
}
}
@ExperimentalGetImage
... ... @@ -173,11 +175,13 @@ class MobileScannerHandler(
torchStateCallback,
zoomScaleStateCallback,
mobileScannerStartedCallback = {
Handler(Looper.getMainLooper()).post {
result.success(mapOf(
"textureId" to it.id,
"size" to mapOf("width" to it.width, "height" to it.height),
"torchable" to it.hasFlashUnit
))
}
},
timeout.toLong(),
cameraResolution,
... ...
... ... @@ -9,9 +9,6 @@ import Flutter
import Foundation
public class BarcodeHandler: NSObject, FlutterStreamHandler {
var event: [String: Any?] = [:]
private var eventSink: FlutterEventSink?
private let eventChannel: FlutterEventChannel
... ... @@ -23,8 +20,9 @@ public class BarcodeHandler: NSObject, FlutterStreamHandler {
}
func publishEvent(_ event: [String: Any?]) {
self.event = event
eventSink?(event)
DispatchQueue.main.async {
self.eventSink?(event)
}
}
public func onListen(withArguments arguments: Any?,
... ...
... ... @@ -232,7 +232,6 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
device.activeFormat.formatDescription)
let hasTorch = device.hasTorch
DispatchQueue.main.async {
completion(
MobileScannerStartParameters(
width: Double(dimensions.height),
... ... @@ -241,16 +240,13 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
textureId: self.textureId ?? 0
)
)
}
return
}
DispatchQueue.main.async {
completion(MobileScannerStartParameters())
}
}
}
/// Stop scanning for barcodes
func stop() throws {
... ...
... ... @@ -121,7 +121,12 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
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])
DispatchQueue.main.async {
result([
"textureId": parameters.textureId,
"size": ["width": parameters.width, "height": parameters.height],
"torchable": parameters.hasTorch])
}
}
} catch MobileScannerError.alreadyStarted {
result(FlutterError(code: "MobileScanner",
... ... @@ -158,12 +163,12 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
private func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
do {
try mobileScanner.toggleTorch(call.arguments as? Int == 1 ? .on : .off)
result(nil)
} catch {
result(FlutterError(code: "MobileScanner",
message: "Called toggleTorch() while stopped!",
details: nil))
}
result(nil)
}
/// Toggles the zoomScale
... ... @@ -177,6 +182,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
}
do {
try mobileScanner.setScale(scale!)
result(nil)
} catch MobileScannerError.zoomWhenStopped {
result(FlutterError(code: "MobileScanner",
message: "Called setScale() while stopped!",
... ... @@ -190,13 +196,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
message: "Error while zooming.",
details: nil))
}
result(nil)
}
/// Reset the zoomScale
private func resetScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
do {
try mobileScanner.resetScale()
result(nil)
} catch MobileScannerError.zoomWhenStopped {
result(FlutterError(code: "MobileScanner",
message: "Called resetScale() while stopped!",
... ... @@ -210,7 +216,6 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
message: "Error while zooming.",
details: nil))
}
result(nil)
}
/// Toggles the torch
... ... @@ -247,16 +252,28 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
}
mobileScanner.analyzeImage(image: uiImage!, position: AVCaptureDevice.Position.back, callback: { [self] barcodes, error in
if error == nil && barcodes != nil && !barcodes!.isEmpty {
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)
}
} else {
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)
} else {
if error != nil {
barcodeHandler.publishEvent(["name": "error", "message": error?.localizedDescription])
}
result(false)
}
})
}
... ...
import AVFoundation
import Flutter
import Foundation
import MLKitBarcodeScanning
extension Error {
func throwNative(_ result: FlutterResult) {
let error = FlutterError(code: localizedDescription, message: nil, details: nil)
result(error)
}
}
extension CVBuffer {
var image: UIImage {
let ciImage = CIImage(cvPixelBuffer: self)
... ...
... ... @@ -144,8 +144,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
}
}
} else {
DispatchQueue.main.async {
self?.sink?(FlutterError(code: "MobileScanner", message: error?.localizedDescription, details: nil))
}
}
})
if(self?.symbologies.isEmpty == false){
// add the symbologies the user wishes to support
... ... @@ -153,11 +155,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
}
try imageRequestHandler.perform([barcodeRequest])
} catch let e {
DispatchQueue.main.async {
self?.sink?(FlutterError(code: "MobileScanner", message: e.localizedDescription, details: nil))
}
}
}
}
}
func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
if #available(macOS 10.14, *) {
... ... @@ -276,6 +280,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
device.unlockForConfiguration()
} catch {
result(FlutterError(code: error.localizedDescription, message: nil, details: nil))
return
}
}
... ... @@ -288,6 +293,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
captureSession.addInput(input)
} catch {
result(FlutterError(code: error.localizedDescription, message: nil, details: nil))
return
}
captureSession.sessionPreset = AVCaptureSession.Preset.photo
// Add video output.
... ...