Flutter侧如何订阅原生代码中创建的监听器?
Flutter侧订阅原生iOS监听器实现方案
一、如何从Flutter侧订阅监听器
你的iOS原生代码已实现注册状态监听器,要让Flutter侧接收状态变化,用EventChannel最合适——它专门处理持续事件流,比MethodChannel更适配监听器场景。具体步骤如下:
1. iOS原生端改造
在你的类中添加EventChannel相关变量,并实现StreamHandler协议:
import Flutter class YourNativeClass: NSObject { var methodChannel: FlutterMethodChannel! var registrationEventChannel: EventChannel? var registrationEventSink: EventSink? var loggedIn = false var mCore: Core? var mRegistrationDelegate: CoreDelegateStub? init(channel: FlutterMethodChannel) { self.methodChannel = channel super.init() // 初始化EventChannel,通道名称需和Flutter侧完全一致 registrationEventChannel = EventChannel(channel.binaryMessenger, name: "com.your.app/registration_state") registrationEventChannel?.setStreamHandler(self) self.initCore() } func initCore() { LoggingService.Instance.logLevel = LogLevel.Debug try? mCore = Factory.Instance.createCore(configPath: "", factoryConfigPath: "", systemContext: nil) try? mCore.start() // 改造监听器,添加事件发送逻辑 mRegistrationDelegate = CoreDelegateStub(onAccountRegistrationStateChanged: { (core: Core, account: Account, state: RegistrationState, message: String) in NSLog("New registration state is \(state) for user id \( String(describing: account.params?.identityAddress?.asString()))\n") if state == .Ok { self.loggedIn = true } else if state == .Cleared { self.loggedIn = false } // 将状态数据封装为Map发送到Flutter self.registrationEventSink?([ "loggedIn": self.loggedIn, "state": state.rawValue, "userId": account.params?.identityAddress?.asString(), "message": message ]) }) mCore?.addDelegate(delegate: mRegistrationDelegate!) } } // 实现StreamHandler协议,处理Flutter的订阅/取消订阅请求 extension YourNativeClass: StreamHandler { func onListen(withArguments arguments: Any?, eventSink: @escaping EventSink) { // 保存事件Sink,后续用来发送事件 registrationEventSink = eventSink // 可选:发送初始状态给Flutter eventSink(["loggedIn": loggedIn, "state": mCore?.currentRegistrationState.rawValue, "message": "初始状态"]) } func onCancel(withArguments arguments: Any?) { // 取消订阅时释放Sink,避免内存泄漏 registrationEventSink = nil } }
2. Flutter侧订阅事件
在Flutter代码中通过EventChannel监听原生发送的状态变化:
import 'package:flutter/services.dart'; class YourFlutterWidget extends StatefulWidget { const YourFlutterWidget({super.key}); @override State<YourFlutterWidget> createState() => _YourFlutterWidgetState(); } class _YourFlutterWidgetState extends State<YourFlutterWidget> { final MethodChannel _methodChannel = MethodChannel('com.your.app/main_channel'); final EventChannel _registrationEventChannel = EventChannel('com.your.app/registration_state'); StreamSubscription? _registrationSubscription; bool _isLoggedIn = false; @override void initState() { super.initState(); // 先调用原生初始化方法(可选,建议确保初始化完成后再监听) _initNativeCore(); // 订阅注册状态变化事件 _subscribeToRegistrationState(); } Future<void> _initNativeCore() async { try { await _methodChannel.invokeMethod('init'); print('原生Core初始化完成'); } on PlatformException catch (e) { print('初始化失败: ${e.message}'); } } void _subscribeToRegistrationState() { _registrationSubscription = _registrationEventChannel.receiveBroadcastStream() .listen((event) { setState(() { _isLoggedIn = event['loggedIn']; }); // 处理其他状态数据 String? userId = event['userId']; int stateCode = event['state']; String message = event['message']; print('注册状态更新: 已登录=$_isLoggedIn, 用户ID=$userId, 状态码=$stateCode, 消息=$message'); }, onError: (error) { print('监听注册状态出错: $error'); }); } @override void dispose() { // 页面销毁时取消订阅,避免内存泄漏 _registrationSubscription?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text(_isLoggedIn ? '已登录' : '未登录'), ), ); } }
二、是否需要始终返回FlutterResult?
不需要,分两种场景:
- FlutterResult仅用于一次性方法调用:比如Flutter调用原生的
init方法,此时可以返回result(true)告知初始化成功,或返回错误信息,但不是强制要求——不过返回结果能让Flutter侧更精准处理流程。 - 监听器的持续事件流不需要FlutterResult:这类场景用EventChannel的Sink发送事件即可,和FlutterResult无关。
只有处理Flutter通过MethodChannel发起的单次请求时,才需要调用FlutterResult返回结果(成功/失败/未实现),比如原生的MethodCall处理逻辑:
func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "init": self.initCore() result(true) // 返回初始化成功 default: result(FlutterMethodNotImplemented) } }
内容的提问来源于stack exchange,提问作者steind.VY
相关产品推荐
相关产品推荐

