stephanmantel
stephanmantel

Reputation: 1827

How do I get the RCTBridgeModule instance from Objective-C

I am currently involved in a React Native project. Currently I try to send an event triggered native (receiving a notification) and then send some information to the ReactNative side.

I made my module: Interface:

#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
#import "RCTBridgeDelegate.h"

@interface PushModule : NSObject <RCTBridgeModule>

-(void) sendNotificationInfo: (NSDictionary*)info;

@end

Implementation:

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

@implementation PushModule

RCT_EXPORT_MODULE()

@synthesize bridge = _bridge;

-(void) sendNotificationInfo:(NSDictionary *)info {
    [bridge.eventDispatcher sendDeviceEventWithName:@"notification" body:info];
}

@end

And then I'd like to access this and call my method:

PushModule* pushModule = [PushModule new];
[pushModule sendNotificationInfo:@{@"title": @"My Title"}];

Trying this, the bridge turned out to be nil, and I never receive anything in React. I did receive my info from Android, so the ReactNative part is OK. Now what I got from all other sources I looked at, it seems that I should not instantiate my module my self, but let the system handle this. So the question is: is that correct and if so, how do I access that instance?

Upvotes: 1

Views: 2072

Answers (1)

stephanmantel
stephanmantel

Reputation: 1827

I solved it myself, eventually ;P

What I did was init my module with the bridge I got from the rootView. So within AppDelegate I extracted the bridge:

I made my own birdge propety in the interface:

@property (nonatomic, strong) RCTBridge* bridge;

And in the implmentation:

@synthesize bridge;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSURL* jsLocation = [[RCTBundleURLProvider sharedSettings]jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsLocation moduleName:@"Metro"initialProperties:nil launchOptions:launchOptions];

    self.bridge = rootView.bridge;

    ...
}

And then whenever I want to send info to the react side I pass the bridge with an initializer that expects the bridge.

PushModule* pushModule = [[PushModule alloc] initWithBridge: self.bridge];
....getting my info....
[pushModule sendNotificationInfo:notificationInfo];

So it turned out I was making it to difficult for myself by not knowing/realizing that the rootView had a bridge itself. Happy day, lovely coding. I hope someone benifits from my struggle.

Upvotes: 1

Related Questions