import Flutter public class OtaPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { var userManager: JLBleManager? var eventSink: FlutterEventSink? public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "ota", binaryMessenger: registrar.messenger()) let eventChannel = FlutterEventChannel(name: "com.example.ota/events", binaryMessenger: registrar.messenger()) let instance = OtaPlugin() registrar.addMethodCallDelegate(instance, channel: channel) eventChannel.setStreamHandler(instance) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? [String: Any] switch call.method { case "init": userManager = JLBleManager.init() result("") case "startUpgrading": let address = arguments?["address"] as? String let filePath = arguments?["filePath"] as? String startUpgrading(address: address, filePath: filePath) result("") case "onOtaClose": onOtaClose() result("") default: result(FlutterMethodNotImplemented) } } public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { eventSink = events return nil } public func onCancel(withArguments arguments: Any?) -> FlutterError? { eventSink = nil userManager?.flutterEventSink = nil return nil } private func startUpgrading(address: String?, filePath: String?) { if userManager?.mBleManagerState == CBManagerState.poweredOn { userManager?.flutterEventSink = eventSink userManager?.startScanBLE(address, filePath: filePath) DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { self.userManager?.stopScanBLE() } } } private func onOtaClose() { userManager?.releaseAllResources() userManager = nil } }