Reputation: 913
I'm writing an iOS app that has two views. Each view is an RCTRootView, created by different React Native component.
I looked into this question (Multiple RCTRootView in a single App) so now I understand it's possible.
But there is a problem. Let the first RCTRootView instance is B, and let the second one is B. A is first shown on the screen, and its react-native counterpart uses a NativeAppEventEmitter to receive events from my native app. At this point, everything works fine. A also has a button to display B on the screen.
When the button is pressed, B is created and displayed. When the button is pressed one more time, B is removed from its superview and destroyed.
But after this, the NativeAppEventEmitter does nothing.
Any kind of hints or comments are welcomed.
Upvotes: 1
Views: 796
Reputation: 913
This problem was related to the symptom that the self.bridge is nil. Though I did @synthesize bridge = _bridge, when processing the event from javascript side, the bridge property was nil, which was unexpected.
Through inspection and web surfing, I found the reason: for the RCTBridgeModule, the lifecycle of the object is very hard to control by the objective-c code. The best practice about the bridge module is to forget about all the details about its lifecycle, and don't make any assumption about its lifecycle.
So, if yourself created the bridge module (maybe using [MyBridge new]
), there might be two different bridge object within your application. You cannot be sure which object would be the one who receives the events from javascript side.
Thus, I'm using the below solution right now.
@implementation EventBridge
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (instancetype) init {
self = [super init];
if ( self ) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cartUpdateNotification:)
name:kCartUpdateNotification
object:nil];
}
return self;
}
+ (void) addObserver:(id)observer selector:(SEL)selector {
[[NSNotificationCenter defaultCenter] addObserver:observer
selector:selector
name:kMenuClickNotification
object:nil];
}
/*
* objc -> js call
*/
+ (void) postEventWithName:(NSString *)name object:(id)object {
[[NSNotificationCenter defaultCenter]
postNotification:[NSNotification notificationWithName:name
object:object]];
}
/*
* js -> objc call when the hamburger is clicked
*/
RCT_EXPORT_METHOD(menuClicked)
{
// This method might be called on the different TopNavViewController object.
[[NSNotificationCenter defaultCenter] postNotificationName:kMenuClickNotification
object:nil];
}
- (void) cartUpdateNotification:(NSNotification*)notification {
[self.bridge.eventDispatcher sendAppEventWithName:@"CartUpdated" body:@{@"item":notification.object}];
}
@end
Upvotes: 1