7

hi I am trying to use multiple event channel to stream data from native side to flutter in iOS swift side when I call the below for setting handler we only get one callback and I want some way to differentiate that which eventsink that I am getting is for Eventchannel1 or EventChannel2

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

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

then the related callback we get this

  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
 }

if the question is not clear let me know so that I can explain it more clearly .

9
  • can you answer the question I have. Commented Apr 10, 2020 at 10:24
  • ok making it small. Commented Apr 10, 2020 at 10:27
  • yes I know how we can stream but the problem is how to get the evensink form the on listen call. EventChannel.setStreamHandler(self) and secondEventChannel.setStreamHandler(self) both have only one on listen call back and I want to know how can we know if the event sink I am getting in the on listen call is from which event channel. Commented Apr 10, 2020 at 10:59
  • I think we can do it by using the withArguments arguments in the on listen call how where we set the arguments. Commented Apr 10, 2020 at 11:03
  • and cannot you simply use two different handlers? and not use self for both cases? Commented Apr 10, 2020 at 11:08

2 Answers 2

7

I loved the problem while looking on GitHub flutter event channel examples and trying different thing. check the below code I add comment so that who ever has the same problem can fixed it easily.

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
 }

when you are listening to this stream in flutter side you can pass the parameter there. check the below code.(flutter side code)

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 Native Code Will Look Like This then .

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
 }

if you need any further help let me know I am here to help.

Sign up to request clarification or add additional context in comments.

3 Comments

I am receiving null in the arguments when I tried to implement multiple event channels.
did you forget to pass parameter when listen the stream
I'm seeing the same behaviour as @DhavalKansara, I see the arguments come through to onListen but when I call receiveBroadcastStream the second time the onCancel gets called with nil
2

Thanks for this answer. The solution works well. I still got some warnings when using it. This was because I updated the state of a Widget based on the eventChannel stream. You might get memory leaks when moving to a new screen if the event channel listener is not cancelled. I used a solution like this instead:

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);

The dispose function of the StatefulWidget looks like:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.