如何在Flutter iOS原生代码(Swift)中使用多个事件通道(EventChannel)

6

嗨,我正在尝试使用多个事件通道将数据从本机端流式传输到Flutter iOS Swift端。当我调用以下设置处理程序时,我们只会得到一个回调,我想知道如何区分我收到的EventChannel1还是EventChannel2的事件池。

let EventChannel1 = FlutterEventChannel(name: "stream1",binaryMessenger: controller.binaryMessenger)
let EventChannel2 = FlutterEventChannel(name: "stream2",binaryMessenger: controller.binaryMessenger)

EventChannel1.setStreamHandler(self)
EventChannel2.setStreamHandler(self)

然后我们得到相关的回调函数

  func onListen(withArguments arguments: Any?,
                     eventSink: @escaping FlutterEventSink) -> FlutterError? {
    debugPrint("On Listen Call")
    EventSink = eventSink//this is for the old event channel now I am using 
    //two event channel.
    //and don't know how to know which event channel is which. on flutter 
    //app startup I listen both stream.
    //and the "on Listen Call" which I print to console print two times 
    //which indicate the I am listen to both stream. 
    //but here I don't know how I know if the eventsink is for which event channel.
    //I want some condition here but don,t know how to implement. if possible 
    //something like this if eventchanel.name == eventchannel1 
    //so that I know which event channel event sink it is and handle it according.
    return nil
 }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    debugPrint("On cancel Call")
    EventSink = nil
    return nil
 }

如果问题不清楚,请告诉我,这样我就可以更清楚地解释了。

你能回答我提出的问题吗? - Zakria Khan
好的,让它变小。 - Zakria Khan
是的,我知道我们可以进行流式传输,但问题在于如何从on listen调用中获取evensink。EventChannel.setStreamHandler(self)和secondEventChannel.setStreamHandler(self)都只有一个on listen回调函数,我想知道如何确定我在on listen调用中获取的事件接收器来自哪个事件通道。 - Zakria Khan
我认为我们可以通过在on listen调用中使用withArguments参数来设置参数,从而实现它。 - Zakria Khan
检查 class SwiftStreamHandler: NSObject, FlutterStreamHandler { - pskink
显示剩余4条评论
2个回答

7

在查看GitHub上flutter事件通道示例并尝试不同的方法时,我很喜欢这个问题。请查看下面的代码,我添加了注释,以便有相同问题的人可以轻松解决它。

let EventChannel1 = FlutterEventChannel(name: "stream1",binaryMessenger: controller.binaryMessenger)
let EventChannel2 = FlutterEventChannel(name: "stream2",binaryMessenger: controller.binaryMessenger)

EventChannel1.setStreamHandler(self)
EventChannel2.setStreamHandler(self)

func onListen(withArguments arguments: Any?,
                     eventSink: @escaping FlutterEventSink) -> FlutterError? {
    debugPrint("On Listen Call")
    //you see the arguments above this are the one which we can use to know which event channel it is.
    EventSink = eventSink
    return nil
 }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    debugPrint("On cancel Call")
    EventSink = nil
    return nil
 }

当你在Flutter端听取这个流时,你可以在那里传递参数。请查看下面的代码。(Flutter端代码)
static const EventChannel1 = const EventChannel("stream1")
static const EventChannel2 = const EventChannel("stream2")

EventChannel1.receiveBroadcastStream(parameter1).listen(_handlestream1);
//here instead of parameter you can pass integer or string 

EventChannel2.receiveBroadcastStream(parameter2).listen(_handlestream2);
////here instead of parameter you can pass integer or string and that can be use in on listen to check which event channel it is.

Swift原生代码将如此呈现。

let EventChannel1 = FlutterEventChannel(name: "stream1",binaryMessenger: controller.binaryMessenger)
let EventChannel2 = FlutterEventChannel(name: "stream2",binaryMessenger: controller.binaryMessenger)

EventChannel1.setStreamHandler(self)
EventChannel2.setStreamHandler(self)

func onListen(withArguments arguments: Any?,
                     eventSink: @escaping FlutterEventSink) -> FlutterError? {
    debugPrint("On Listen Call")

    //here we will check the argument we pass will listen to this eventstream.
    if arguments as? Int == parameter1 { 
        // here you unwrap the argument and check it with parameter you pass
        //if this check pass its mean that its is event channel1 and handle that here
        Evensink1 = eventSink 
    }

    if arguments as? Int == parameter2 {
        //if this check pass mean eventchannel2 and handle that here
        EventSink = eventSink
    }

    return nil
 }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    debugPrint("On cancel Call")
    EventSink = nil
    return nil
 }

如果您需要进一步帮助,请告诉我,我会在这里提供帮助。

当我尝试实现多个事件通道时,我的参数中出现了null。 - Dhaval Kansara
你在监听流时是否忘记传递参数了? - Zakria Khan
我看到和 @DhavalKansara 一样的行为,我看到参数传递到 onListen,但是当我第二次调用 receiveBroadcastStream 时,onCancel 会被带有 nil 的参数调用。 - opsb

2

谢谢你的答案。这个解决方案很好用。但是在使用时我仍然收到了一些警告。这是因为我根据eventChannel流更新了Widget的状态。如果事件通道侦听器没有被取消,当移动到新屏幕时可能会发生内存泄漏。我使用了以下解决方案:

static const EventChannel1 = const EventChannel("stream1")
static const EventChannel2 = const EventChannel("stream2")

StreamSubscription eventChannelListener1 = EventChannel1.receiveBroadcastStream(parameter1).listen(_handlestream1, onError: _onError);
StreamSubscription eventChannelListener2 = EventChannel2.receiveBroadcastStream(parameter2).listen(_handlestream2, onError: _onError);

StatefulWidget的dispose函数如下:

 @override
  void dispose() {
    super.dispose();      
     eventChannelListener1.cancel();
     eventChannelListener2.cancel();
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接