2016-08-07 92 views
4

但我注意到当我从另一个方法调用它时,我的桥变量是零。我相信这是因为只有在从JavaScript调用桥接方法时才设置桥接。我已经尝试了从创建委托创建SingleTon类的一切。以上都没有工作,我不明白为什么它只能在我从Javascript调用的方法中使用。这里是我的类当我从另一个方法调用方法时,React-native Bridge是Nil

Helper.h

#import "RCTBridge.h" 
#import "AppDelegate.h" 
#import "RCTEventEmitter.h" 

@interface Helper : RCTEventEmitter <RCTBridgeModule> 

-(void) auth; 

@end 

这里是我的.m文件: Helper.m

#import "AppDelegate.h" 
#import "Helper.h" 
#import "RCTBridge.h" 
#import "RCTEventDispatcher.h" 

@implementation Helper 
RCT_EXPORT_MODULE(); 

@synthesize bridge = _bridge; 

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


RCT_EXPORT_METHOD(auth) 
{ 
    [self.bridge.eventDispatcher sendDeviceEventWithName:@"SpotifyHelper" body:@{@"Login": @true}]; 
    printf("Auth"); 
} 

RCT_EXPORT_METHOD(play:(NSString *) uri first: id) 
{ 
    AppDelegate *appDelegate = [[AppDelegate alloc] init]; 
    [appDelegate play:uri second:id]; 
} 

@end 

我对方法调用从我委托这样的内部:

[[AppDelegate alloc] init] auth] 

这是我认为它没有初始化的原因。我不知道如何让RCTBridge变量不为零。任何帮助?

回答

7

的问题是在这里:

[[AppDelegate alloc] init] auth] 

当您使用宏RCT_EXPORT_MODULE()作出反应,本地人实例化类的你,以及所有后续alloc/init旨意创建新实例,无关的原件。桥将不会在这些新的实例中被实例化。

您可以使用NSNotifications解决您的问题。

Helper.h:

#import "RCTEventEmitter.h" 

@interface Helper : RCTEventEmitter 

+ (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload; 

@end 

Helper.m:

#import "Helper.h" 

@implementation Helper 

RCT_EXPORT_MODULE(); 

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

- (void)startObserving 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(emitEventInternal:) 
               name:@"event-emitted" 
              object:nil]; 
} 

- (void)stopObserving 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)emitEventInternal:(NSNotification *)notification 
{ 
    [self sendEventWithName:@"SpotifyHelper" 
        body:notification.userInfo]; 
} 

+ (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload 
{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted" 
                 object:self 
                userInfo:payload]; 
} 

// Remaining methods 

@end 

还有很长的讨论帖点击这里:What is the method can be used to send an event from native module to JS

2

我想补充到oar.garuna的回答(这是只是一个完整的救星),对于那些有多个事件并想要处理的人,下面的代码会设置一个观察者,然后我们可以静态调用emitEventWithName和帮手将适当地处理它并发送该事件。

eventHelper.h

@interface eventHelper : RCTEventEmitter 

    + (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload; 

@end 

eventHelper.m

@implementation eventHelper 

    RCT_EXPORT_MODULE(); 

    // The list of available events 
    - (NSArray<NSString *> *)supportedEvents { 
    return @[@"EventLoggedOut"]; 
    } 

    // This function listens for the events we want to send out and will then pass the 
    // payload over to the emitEventInternal function for sending to Javascript 
    - (void)startObserving 
    { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(emitEventInternal:) 
              name:@"event-emitted" 
              object:nil]; 
    } 

    // This will stop listening if we require it 
    - (void)stopObserving 
    { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    } 

    // This will actually throw the event out to our Javascript 
    - (void)emitEventInternal:(NSNotification *)notification 
    { 
    // We will receive the dictionary here - we now need to extract the name 
    // and payload and throw the event 
NSArray *eventDetails = [notification.userInfo valueForKey:@"detail"]; 
    NSString *eventName = [eventDetails objectAtIndex:0]; 
    NSDictionary *eventData = [eventDetails objectAtIndex:1]; 

    [self sendEventWithName:eventName 
        body:eventData]; 
    } 

    // This is our static function that we call from our code 
    + (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload 
    { 
    // userInfo requires a dictionary so we wrap out name and payload into an array and stick 
    // that into the dictionary with a key of 'detail' 
    NSDictionary *eventDetail = @{@"detail":@[name,payload]}; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted" 
                object:self 
                userInfo:eventDetail]; 
    } 

@end 

一旦部分已经设置你应该然后能够从任何地方如下拨打电话到我们的静态功能emitEventWithName

[eventHelper emitEventWithName:@"myEventName" andPayload:@{@"key":@"value1"}]; 

希望能帮助别人!

+0

今天帮助我 - 谢谢! –

+0

你在哪里调用startObserving方法? –

+0

@FernandoCaride'startObserving'和'stopObserving'函数是在.h文件中实现的RCTEventEmitter类的重写。所以这些应该在你的应用程序启动并且实例化时自动调用。 (希望有道理!) –

相关问题