如何在混编Objective-C与Swift的Flutter项目中实现EventChannel?
Objective-C与Swift混编中实现Flutter EventChannel方案
针对你在混编项目中需要将Objective-C类里的NFC/BLE回调通过Flutter EventChannel传递给Flutter页面的需求,以下是具体实现步骤:
1. 修正Objective-C类的Block属性与方法
首先调整MyController.h中的Block属性声明,将strong改为copy(Block属性规范用法,避免栈Block释放问题),并补充设置Block的方法声明:
typedef void(^NfcBlock)(bool isSuccess); typedef void(^BleBlock)(bool isSuccess); @interface MyController : NSObject<NfcDelegate, BleServiceDelegate,CBCentralManagerDelegate> @property (nonatomic,strong) BlePassService *blePassService; @property (nonatomic,strong) NfcPassService *nfcService; @property (nonatomic,strong) MobilePass *mobilePass; @property (nonatomic, copy) NfcBlock nfcBlock; // 改为copy @property (nonatomic, copy) BleBlock bleBlock; // 改为copy // 补充设置Block的方法声明 - (void)setNfcBlock:(NfcBlock)nfcBlock; - (void)setBleBlock:(BleBlock)bleBlock; @end
在MyController.m中实现设置方法,并在NFC/BLE代理回调里触发Block:
@implementation MyController - (void)setNfcBlock:(NfcBlock)nfcBlock { _nfcBlock = nfcBlock; } - (void)setBleBlock:(BleBlock)bleBlock { _bleBlock = bleBlock; } // NFC代理方法示例(根据你的实际代理方法调整) - (void)nfcOperationDidFinishWithSuccess:(BOOL)isSuccess { if (self.nfcBlock) { self.nfcBlock(isSuccess); } } // BLE代理方法示例(根据你的实际代理方法调整) - (void)bleConnectionDidFinishWithSuccess:(BOOL)isSuccess { if (self.bleBlock) { self.bleBlock(isSuccess); } } @end
2. 在Swift的AppDelegate中配置Flutter EventChannel
首先添加EventChannel相关属性与协议实现,将Block回调与EventChannel的事件发送关联:
import UIKit import Flutter @UIApplicationMain class AppDelegate: FlutterAppDelegate { private var eventSink: FlutterEventSink? private var passKit: MyController? // 你的MyController实例 override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { GeneratedPluginRegistrant.register(with: self) // 初始化EventChannel guard let controller = window?.rootViewController as? FlutterViewController else { return super.application(application, didFinishLaunchingWithOptions: launchOptions) } let eventChannel = FlutterEventChannel(name: "com.your.app/nfc_ble_events", binaryMessenger: controller.binaryMessenger) eventChannel.setStreamHandler(self) // 初始化passKit(根据你的实际逻辑调整) passKit = MyController() return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // NFC回调方法,通过EventChannel发送事件到Flutter func nfcCallback(isSuccess: Bool) { eventSink?(["type": "nfc", "success": isSuccess]) } // BLE回调方法,通过EventChannel发送事件到Flutter func bleCallback(isSuccess: Bool) { eventSink?(["type": "ble", "success": isSuccess]) } // 原有的方法(保持你的业务逻辑) func handleMethodCall(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "initState": guard let passKit = passKit else { return } passKit.initial() passKit.setNfcBlock(nfcCallback) passKit.setBleBlock(bleCallback) result("success") // 其他方法处理... default: result(FlutterMethodNotImplemented) } } } // 实现FlutterStreamHandler协议 extension AppDelegate: FlutterStreamHandler { func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { eventSink = events return nil } func onCancel(withArguments arguments: Any?) -> FlutterError? { eventSink = nil return nil } }
3. Flutter端监听EventChannel
在Flutter页面中监听事件,处理来自原生的NFC/BLE结果:
import 'package:flutter/services.dart'; class YourFlutterPage extends StatefulWidget { const YourFlutterPage({super.key}); @override State<YourFlutterPage> createState() => _YourFlutterPageState(); } class _YourFlutterPageState extends State<YourFlutterPage> { static const EventChannel _eventChannel = EventChannel('com.your.app/nfc_ble_events'); @override void initState() { super.initState(); // 监听原生事件 _eventChannel.receiveBroadcastStream().listen((event) { String type = event['type']; bool success = event['success']; if (type == 'nfc') { // 处理NFC操作结果 print("NFC操作结果:$success"); } else if (type == 'ble') { // 处理BLE连接结果 print("BLE连接结果:$success"); } }); } @override Widget build(BuildContext context) { // 你的页面UI return Scaffold( appBar: AppBar(title: const Text("NFC/BLE测试")), ); } }
关键注意点
- 确保Objective-C中的代理方法正确触发Block,比如在NFC/BLE操作完成的回调里调用
self.nfcBlock(isSuccess); - EventChannel的名称要保持原生与Flutter端一致(示例中为
com.your.app/nfc_ble_events); - 当不需要监听时,
eventSink要置为nil,避免内存泄漏。
内容的提问来源于stack exchange,提问作者bakboem
相关产品推荐
相关产品推荐

