React Native - dispatching events from Native to JavaScript in AppDelegate (iOS)

In my React native application, I am trying to send events from Native Code to JavaScript in AppDelegate. To do this, I call:

[self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder" body:@{@"name": eventName}]; 

In my application. Of course, for this I need to import:

import "RCTBridge.h"

import "RCTEventDispatcher.h"

and synthesize a bridge

 @synthesize bridge = _bridge; 

But the event after that, the bridge variable does not exist. To make this error go away, I made the AppDelegate application comply with the RCTBridgeModule protocol as follows:

 AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeModule> 

And then in my AppDelegate.m I did:

 RCT_EXPORT_MODULE() 

In the end, my bridge is finally not a mistake, but every time I use it in AppDelegate, it is zero.

Where am I going wrong?

Thanks in advance.

+6
source share
2 answers

RCTBridge creates new instances of each module class at startup, so when exporting AppDelegate as a bridge module, you tell the bridge to create a new AppDelegate and give it a bridge instance.

iOS also creates an instance of AppDelegate when your application starts, but the instance created by iOS is not the same instance created by RCTBridge.

So, you have two instances of AppDelegate: the one with which you are trying to access self.bridge, which was not created by RCTBridge, and therefore does not have a link to it, and the one that was created by RCTBridge, which has a bridge but is not delegate for your UIApplication and does not execute your code.

You have several options:

1) you can transfer an instance of AppDelegate to the bridge when you create it using the RCMBridgeDelegate extraModules method. This allows you to tell the bridge to use an existing module instance, instead of creating a new one.

2) you can access the bridge through RCTRootView instead of making AppDelegate into the module so that it gets the self.bridge property.

3) Move the logic that should talk to the bridge from AppDelegate to the new module. If it is necessary to trigger an event inside AppDelegate, use NSNotifications to communicate with the module instance (we use this template for RCTPushNotificationManager).

Of these parameters

Option 1) is probably the most difficult to do right.

Option 2) is probably the easiest to do, because you presumably already have an instance of RCTRootView in AppDelegate that you can reference.

Option 3) is ideal from a technical point of view, since it prevents accidental dispatch of events before the bridge is properly initialized (which can lead to failure or lead to unexpected results).

+13
source

Alternatively, you can use NSNotificationCenter.

For example, to handle incoming push notifications in AppDelegate

 didReceiveRemoteNotification: 

Publish NSNotification. Observe this NSNotification by name in a subclass of RCTEventEmitter. Then call

 [self sendEventWithName:@"eventName" body:eventBody]; 

in the corresponding selector.

See: Send and receive messages through NSNotificationCenter in Objective-C?

+1
source

All Articles