Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RCTEventEmitter bridge is not set #15421

Closed
Symous opened this issue Aug 9, 2017 · 9 comments
Closed

RCTEventEmitter bridge is not set #15421

Symous opened this issue Aug 9, 2017 · 9 comments
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@Symous
Copy link

Symous commented Aug 9, 2017

Is this a bug report?

Not confirm.

Have you read the Contributing Guidelines?

Yes, I have follow all sept of this document of how to use RCTEventEmitter to send event from Native to JS.but still meet this error.

Environment

  1. react-native -v: 0.45.1
  2. node -v: 8.1.2
  3. npm -v: 5.30

Then, specify:

  • Target Platform: iOS
  • Development Operating System:macOS
  • Build tools:iOS 10

Steps to Reproduce

  1. Create a helper class that can emit event from iOS native to JS according to the document.
  2. invoke sendEventWithName method any where in the code we need to emit event.

Expected Behavior

JS will receive the event and catch the data.

Actual Behavior

[tid:com.facebook.react.ShadowQueue] Exception 'bridge is not set. 
This is probably because you've explicitly synthesized the bridge in RCTCameraEvent, 
even though it's inherited from RCTEventEmitter.'
was thrown while invoking capture on target CameraManager with params (
        {
        audio = 0;
        barCodeTypes =         (
        );
        description = "";
        mirrorImage = 0;
        mode = 1;
        playSoundOnCapture = 1;
        preferredTimeScale = 30;
        quality = 0;
        target = 1;
        title = "";
        totalSeconds = 10;
        type = 1;
    },
    3892,
    3893
)

Reproducible Demo

EventHelper.h

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface RCTCameraEvent : RCTEventEmitter<RCTBridgeModule>

@end

EventHelper.m

#import "RCTCameraEvent.h"

@implementation RCTCameraEvent

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
    return @[@"CustomEvent"];
}

- (void)sendEvent2JS
{
    [self sendEventWithName:@"CustomEvent" body:@{@"name": @"111"}];
}

@end

invoke send event method in code

RCTCameraEvent * cameraEvent = [[RCTCameraEvent alloc]init];
[cameraEvent sendEvent2JS];

All I want to do is create a helper class so that I can invoke the send event method anywhere I need.

I have look into many issues (#8714) and search related answer on Google and stackoverflow but still can not found a perfect solution using RCTEventEmitter. there are lots of developers like me meet this problem and react native haven't provide us a standard code demo or completely document.

@hfossli
Copy link
Contributor

hfossli commented Aug 10, 2017

You shouldn't init RCTCameraEvent yourself. It will be initialized by react native. You must try to communicate with that instance in some way. For example your AppDelegate may send a notification which RCTCameraEvent subscribes to on init. You may then forward that information to js using the [self sendEventWithName:@"CustomEvent" body:@{@"name": @"111"}];

@hfossli
Copy link
Contributor

hfossli commented Aug 10, 2017

I agree this is a bit tricky and some help from the framework and documentation would be nice

@hfossli
Copy link
Contributor

hfossli commented Aug 10, 2017

This is also a very nice way. https://gist.github.com/brennanMKE/1ebba84a0fd7c2e8b481e4f8a5349b99 I think this is exactly what you are looking for?

@Liqiankun
Copy link

Finally, I got the solution.

#import "RNNotification.h"
@implementation RNNotification

RCT_EXPORT_MODULE();

+ (id)allocWithZone:(NSZone *)zone {
    static RNNotification *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

- (NSArray<NSString *> *)supportedEvents
{
    return @[@"EventReminder"];
}

- (void)sendNotificationToReactNative
{
    [self sendEventWithName:@"EventReminder" body:@{@"name": @"name"}];
}

When you use it!

RNNotification *notification = [RNNotification allocWithZone: nil];
[notification sendNotificationToReactNative]

@hfossli
Copy link
Contributor

hfossli commented Oct 10, 2017

Yep, singleton pattern is one option.

@huyhai
Copy link

huyhai commented Oct 30, 2017

you save my day @Liqiankun
thank you!

@stale
Copy link

stale bot commented Dec 29, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Dec 29, 2017
@stale stale bot closed this as completed Jan 5, 2018
@JefferyHus
Copy link

@Liqiankun I did the same thing as you, still getting a damn error in my AppDelegate No visible @interface for 'RTNEventManager' declares the selector 'socketOpenConnection:userNumber:'

These are my files:

RTNEventManager.h

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface RTNEventManager : RCTEventEmitter <RCTBridgeModule>

@end

RTNEventManager.m

#import "RTNEventManager.h"

@implementation RTNEventManager

RCT_EXPORT_MODULE();

+ (id)allocWithZone:(NSZone *)zone {
    static RTNEventManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

- (NSArray<NSString *> *)supportedEvents
{
  return @[@"onOpened"];
}

- (void)socketOpenConnection
{
  [self sendEventWithName:@"onOpened" body:@{@"callername": @"205-966-1916", @"username": @"9542493959"}];
}

@end

and then inside my AppDelegate.m I do this

#import "RTNEventManager.h"
...
RTNEventManager *manager = [RTNEventManager allocWithZone: nil];
[manager socketOpenConnection];

And when building it pops up the same error again and again.

@ogil7190
Copy link

ogil7190 commented Sep 8, 2018

expose an interface like this

'- (void) socketOpenConnection'

in your ".h" file

@facebook facebook locked as resolved and limited conversation to collaborators Jan 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

6 participants