In my React native app, I am trying to send events from Native Code to JavaScript in the AppDelegate. To do this I call:
[self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder"
body:@{@"name": eventName}];
In my app delegate. Of course to do this I need to import:
and synthesize the bridge
@synthesize bridge = _bridge;
But event after this, the bridge variable doesn't exist. To make this error go away I made my AppDelegate conform to the RCTBridgeModule protocol like so:
AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeModule>
And then in my AppDelegate.m, I did:
RCT_EXPORT_MODULE()
After all that my bridge is finally not erroring, but Everytime I use it in the AppDelegate, it is nil.
Where am I going wrong?
Thanks in advance.
RCTBridge creates new instances of each module class when it starts up, so when you export your AppDelegate as a bridge module, you're telling the bridge to create a new AppDelegate, and give it a bridge instance.
iOS also creates an instance of AppDelegate when your application launches, but the instance created by iOS isn't the same instance created by RCTBridge.
So basically, you have two instances of AppDelegate: the one you're trying to access self.bridge from, which wasn't created by RCTBridge and so doesn't have a reference to it, and the one created by RCTBridge, which has a bridge, but isn't the delegate for your UIApplication, and isn't running your code.
You have a few options:
1) you could pass your AppDelegate instance into the bridge when you create it by using the RCTBridgeDelegate's extraModules method. This lets you tell the bridge to use an existing instance of a module, instead pf creating a new one.
2) you could access the bridge via your RCTRootView instead of making your AppDelegate into a module so that it gets given a self.bridge property.
3) Move the logic that needs to talk to the bridge out of AppDelegate into a new module. If it needs to be triggered by an event inside AppDelegate, use NSNotifications to communicate with the module instance (we use this pattern for RCTPushNotificationManager).
Of these options,
Option 1) is probably the most complicated to do correctly.
Option 2) is probably the easiest to do because you presumably already have an instance of RCTRootView in your AppDelegate that you can reference.
Option 3) is ideal from a technical perspective, because it prevents you from accidentally sending events before the bridge is properly initialized (which might crash, or behave unexpectedly).
Alternatively you can use NSNotificationCenter.
For example to process incoming push notifications in AppDelegate
didReceiveRemoteNotification:
post a NSNotification. Observe this NSNotification by name in a subclass of RCTEventEmitter. Then call
[self sendEventWithName:@"eventName" body:eventBody];
in the respective selector.
See: Send and receive messages through NSNotificationCenter in Objective-C?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With