Listening for events in react native ios

Viewed 13205

I cannot for the life of me get an event to properly send from iOS native across the bridge to the react native JS context. On the Objective-C side I want to have a module to easily send events across the bridge. I have called this class EventEmitter and its definition is as follows:

// EventEmitter.h

#import "RCTBridge.h"
#import "RCTEventDispatcher.h"

@interface EventEmitter : NSObject<RCTBridgeModule>

  - (void)emitEvent:(NSString *) eventName withData:(id) eventData;

@end

and the implementation:

// EventEmitter.m

#import "EventEmitter.h"

@implementation EventEmitter

  RCT_EXPORT_MODULE();

  @synthesize bridge = _bridge;

  - (void)emitEvent:(NSString *) eventName withData:(id) eventData
  {
    NSLog( @"emitting %@ with data %@", eventName, [eventData description] );
    [[_bridge eventDispatcher] sendDeviceEventWithName:eventName body:eventData];
    [[_bridge eventDispatcher] sendAppEventWithName:eventName body:eventData];
  }

@end

I'm using both sendDeviceEvent and sendAppEvent because I can't get either to work.

On the JS side of things I register to receive these events in the global namespace of one of my modules (so that I know the event subscription will happen before the event is emitted). I register like this:

console.log( 'ADDING EVENT LISTENERS' );
NativeAppEventEmitter.addListener( 'blah', test => console.log( 'TEST1', test ) );
DeviceEventEmitter.addListener( 'blah', test => console.log( 'TEST2', test ) );

In my log statements I get the following:

2016-03-19 12:26:42.501 [trace][tid:com.facebook.React.JavaScript] ADDING EVENT LISTENERS
2016-03-19 12:26:43.613 [name redacted][348:38737] emitting blah with data [data redacted]

So I can tell that I am sending both an app event and a device event with the tag blah and I have registered to listen for the blah event with both the DeviceEventEmitter and NativeAppEventEmitters but I'm not getting called back in the listeners.

What am I doing wrong?? Thanks for reading!

6 Answers

You have to use your emitter class like this

[[self.bridge moduleForClass:[RNNotification class]] sendNotificationToReactNative];

You can try following solution to to send event from iOS to React Native

RNEventEmitter.m

  #import <Foundation/Foundation.h>
  #import <React/RCTBridgeModule.h>
  #import <React/RCTEventEmitter.h>

   @interface RCT_EXTERN_MODULE(RNEventEmitter, RCTEventEmitter)
    RCT_EXTERN_METHOD(supportedEvents)
   @end

RNEventEmitter.swift

 import Foundation

 @objc(RNEventEmitter)
  open class RNEventEmitter: RCTEventEmitter {

     public static var emitter: RCTEventEmitter!

     override init() {
     super.init()
     RNEventEmitter.emitter = self
   }

    open override func supportedEvents() -> [String] {
      ["onReady", "onPending", "onFailure"]      // etc.
    }
}

Your file from where you are going to emit event add below line

  RNEventEmitter.emitter.sendEvent(withName: "onReady", body: [["status":"Connected","data":["name":dev?.name,"deviceId":dev?.identifier]]]);

React Native file

    const emitter = new NativeEventEmitter(NativeModules.RNEventEmitter)
    

In your Bridgin-Header file import

#import <React/RCTEventEmitter.h>

In your useEffect

emitter.addListener('onReady', (data: any) => {
        console.log("addListener", data);
        Alert.alert(JSON.stringify(data))
    });
Related