Listening for events in react native ios
I've tried dispatching events and it seems bridge
is not initialised when you create new EventEmitter
instances manually by using [EventEmitter alloc] init]
You should let react-native create instances. I checked native components and they're using -(void)setBridge:(RCTBridge *)bridge
method to do initialisation work. Please check out RCTLinkingManager
to see an example. It's using NSNotificationCenter
to handle events.
// registering for RCTOpenURLNotification evet when the module is initialised with a bridge
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleOpenURLNotification:)
name:RCTOpenURLNotification
object:nil];
}
// emitting openURL event to javascript
- (void)handleOpenURLNotification:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"openURL"
body:notification.userInfo];
}
// creating RCTOpenURLNotification event to invoke handleOpenURLNotification method
+ (BOOL)application:(UIApplication *)application
openURL:(NSURL *)URL
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSDictionary<NSString *, id> *payload = @{@"url": URL.absoluteString};
[[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification
object:self
userInfo:payload];
return YES;
}
You can using NativeEventEmitter
// register eventEmitter
const {NGListener} = NativeModules; // NSListener is my class
this.eventEmitter = new NativeEventEmitter(NativeModules.NGListener);
this.eventEmitter.addListener('CancelEvent', (data) => {
console.log(data);
})
In ObjectiveC , you can create
#import <RCTViewManager.h>
#import <RCTEventEmitter.h>
@interface NGListener: RCTEventEmitter <RCTBridgeModule>
@end
@implementation NGListener
RCT_EXPORT_MODULE();
- (NSArray<NSString*> *)supportedEvents {
return @[@"CancelEvent", @"OKEvent"];
}
// And you sent event you want from objectC to react-native
[self sendEventWithName:@"CancelEvent" body:@"Tap`enter code here` on Cancel button from Objc"];
I wrote sample example to handle event from react-native to objectivec and opposite. https://github.com/lengocgiang/event-listener Hope this help!!
In my case I got this working by keeping a value of the bridge from RCTRootView and passing it to the Emitter Instance.
@implementation AppDelegate {
RCTBridge *rootBridge;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
......
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MyApp"
initialProperties:nil
launchOptions:launchOptions];
rootBridge = rootView.bridge;
.......
}
- (IBAction)doAction:(id)sender {
BridgeEvents *events = [[BridgeEvents alloc] init];
[events setBridge:rootBridge];
[events doMyAction];
}
In my Emitter Class:
#import "RCTEventEmitter.h"
@interface BridgeEvents : RCTEventEmitter <RCTBridgeModule>
- (void)doMyAction;
@end
#import "BridgeEvents.h"
@implementation BridgeEvents
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents {
return @[@"onEvent"];
}
- (void)doMyAction {
[self sendEventWithName:@"onEvent" body:@""];
}
@end