import Flutter import Foundation import NpIosCore class MessageRelayChannelHandler: NSObject, FlutterStreamHandler { override init() { do { Self.idLock.lock() defer { Self.idLock.unlock() } id = Self.nextId Self.nextId += 1 } super.init() } func onMethodCall(call: FlutterMethodCall, result: FlutterResult) { let args = call.arguments as? Dictionary do { switch call.method { case "broadcast": try broadcast( event: (args?["event"] as? String).unwrap(), data: args?["data"] as? String, result: result ) default: result(FlutterMethodNotImplemented) } } catch let error as AppError { result(FlutterError(code: "systemException", message: error.message, details: "\(error.stackTrace)")) } catch { result(FlutterError(code: "systemException", message: "\(error)", details: nil)) } } func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { Self.evLock.lock() defer { Self.evLock.unlock() } Self.eventSinks[id] = events return nil } func onCancel(withArguments arguments: Any?) -> FlutterError? { Self.evLock.lock() defer { Self.evLock.unlock() } Self.eventSinks.removeValue(forKey: id) return nil } private func broadcast(event: String, data: String?, result: FlutterResult) { Self.evLock.lock() defer { Self.evLock.unlock() } for s in Self.eventSinks.values { var map = ["event": event] if data != nil { map["data"] = data } s(data) } result(nil) } static let eventChannel = "\(K.libId)/message_relay_event" static let methodChannel = "\(K.libId)/message_relay_method" private static var eventSinks: [Int:FlutterEventSink] = [:] private static var evLock = NSRecursiveLock() private static var nextId = 0 private static var idLock = NSRecursiveLock() private let id: Int }