2016-03-18 11 views
6

私の人生にとっては、iOSネイティブからブリッジを越えて反応するネイティブJSコンテキストに正しくイベントを送信できません。 Objective-C側では、ブリッジ経由でイベントを簡単に送信するモジュールを用意したいと考えています。私は次のように、このクラスの持つEventEmitterとその定義があると呼ばれています:反応したネイティブのiosでのイベントのリッスン

// EventEmitter.h 

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

@interface EventEmitter : NSObject<RCTBridgeModule> 

    - (void)emitEvent:(NSString *) eventName withData:(id) eventData; 

@end 

と実装:

// EventEmitter.m 

#import "EventEmitter.h" 

@implementation EventEmitter 

    RCT_EXPORT_MODULE(); 

    @synthesize bridge = _bridge; 

    - (void)emitEvent:(NSString *) eventName withData:(id) eventData 
    { 
    NSLog(@"emitting %@ with data %@", eventName, [eventData description]); 
    [[_bridge eventDispatcher] sendDeviceEventWithName:eventName body:eventData]; 
    [[_bridge eventDispatcher] sendAppEventWithName:eventName body:eventData]; 
    } 

@end 

私はどちらかが仕事を得ることができないので、私はsendDeviceEventとsendAppEventの両方を使用しています。

JSサイドでは、自分のモジュールのグローバル名前空間でこれらのイベントを受け取るように登録します(イベントサブスクリプションはイベントが発生する前に発生することがわかっています)。私のログステートメントで

console.log('ADDING EVENT LISTENERS'); 
NativeAppEventEmitter.addListener('blah', test => console.log('TEST1', test)); 
DeviceEventEmitter.addListener('blah', test => console.log('TEST2', test)); 

私は、次を得る:私はこのような登録

2016-03-19 12:26:42.501 [trace][tid:com.facebook.React.JavaScript] ADDING EVENT LISTENERS 
2016-03-19 12:26:43.613 [name redacted][348:38737] emitting blah with data [data redacted] 

だから私は、私はタグ何とかしてアプリイベントおよびデバイスイベントの両方を送信し、私だと言うことができますDeviceEventEmitterとNativeAppEventEmittersの両方でblahイベントをリスンするよう登録していますが、リスナーでコールバックされていません。

私は何が間違っていますか?読んでくれてありがとう!

+0

をINITINGながら

#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"}]; } 

が、これはOKになります。 DeviceEventEmitterはreact-native.jsに公開されています。 AppStateモジュールを見てみましょう:https://github.com/facebook/react-native/blob/ad8a33586410c6f9048983f64f8f86e0715e73b8/Libraries/AppState/AppState.js 試してみることができるのは、イベントを送信するサードパーティのモジュールです。そのコードを見てください:https://js.coach/ –

+0

クイック返信マーティンありがとう。私は、NativeAppEventEmitterまたはDeviceEventEmitterのいずれかを使用するサンプルを探していて、それらのすべてが私のものと同じように見えます。私が考えることができるのは、EventEmitterを独自のクラスとして持っているため、emitEventメソッドにアクセスする前に、標準のalloc/initを実行してインスタンスを取得することです。私が自分の言葉でそれを割り当てているという事実は何の効果もありますか? –

+0

[EventEmitter alloc] initによって新しいEventEmitterインスタンスを作成していますか?もしそうなら、emitEventメソッドで_bridgeの値をデバッグできますか? – halilb

答えて

2

私は、イベントをディスパッチしようとしました、あなたがあなたが反応し、ネイティブのインスタンスを作成してみましょうする必要があり[EventEmitter alloc] init]

を使用して手動で新しいEventEmitterインスタンスを作成するときにbridgeが初期化されていないようです。私はネイティブコンポーネントをチェックして、彼らは-(void)setBridge:(RCTBridge *)bridgeメソッドを使って初期化作業を行っています。例を見るにはRCTLinkingManagerをチェックしてください。イベントを処理するのにNSNotificationCenterを使用しています。

// registering for RCTOpenURLNotification evet when the module is initialised with a bridge 
- (void)setBridge:(RCTBridge *)bridge 
{ 
    _bridge = bridge; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(handleOpenURLNotification:) 
               name:RCTOpenURLNotification 
              object:nil]; 
} 

// emitting openURL event to javascript 
- (void)handleOpenURLNotification:(NSNotification *)notification 
{ 
    [_bridge.eventDispatcher sendDeviceEventWithName:@"openURL" 
               body:notification.userInfo]; 
} 

// creating RCTOpenURLNotification event to invoke handleOpenURLNotification method 
+ (BOOL)application:(UIApplication *)application 
      openURL:(NSURL *)URL 
    sourceApplication:(NSString *)sourceApplication 
     annotation:(id)annotation 
{ 
    NSDictionary<NSString *, id> *payload = @{@"url": URL.absoluteString}; 
    [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification 
                 object:self 
                userInfo:payload]; 
    return YES; 
} 
+0

これは正しい方向に私を指摘しました。 –

3

あなたがObjectiveCで

// register eventEmitter 
    const {NGListener} = NativeModules; // NSListener is my class 
    this.eventEmitter = new NativeEventEmitter(NativeModules.NGListener); 
    this.eventEmitter.addListener('CancelEvent', (data) => { 
     console.log(data); 
    }) 

NativeEventEmitterを使用することができます、あなたは私が反応し、ネイティブobjectivecと反対してからイベントを処理するためのサンプル例を書いた

#import <RCTViewManager.h> 
    #import <RCTEventEmitter.h> 
    @interface NGListener: RCTEventEmitter <RCTBridgeModule> 
    @end 

    @implementation NGListener 

    RCT_EXPORT_MODULE(); 

    - (NSArray<NSString*> *)supportedEvents { 
     return @[@"CancelEvent", @"OKEvent"]; 
    } 
    // And you sent event you want from objectC to react-native 
    [self sendEventWithName:@"CancelEvent" body:@"Tap`enter code here` on Cancel button  from Objc"]; 

作成することができます。 https://github.com/lengocgiang/event-listener このヘルプが必要です。

+0

それぞれの 'init'はどんな順番で重要ですか? Obj-CのReactNative部分? – Trip

1

私の場合、私はRCTRootViewからブリッジの値を保持し、それをエミッタインスタンスに渡すことでこれを実現しました。私のエミッタクラスで

@implementation AppDelegate { 
    RCTBridge *rootBridge; 
} 

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

    ...... 

    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 
                 moduleName:@"MyApp" 
               initialProperties:nil 
                launchOptions:launchOptions]; 
    rootBridge = rootView.bridge; 

    ....... 

} 

- (IBAction)doAction:(id)sender { 
    BridgeEvents *events = [[BridgeEvents alloc] init]; 
    [events setBridge:rootBridge]; 
    [events doMyAction]; 
} 

#import "RCTEventEmitter.h" 

@interface BridgeEvents : RCTEventEmitter <RCTBridgeModule> 
- (void)doMyAction; 
@end 

#import "BridgeEvents.h" 

@implementation BridgeEvents 

RCT_EXPORT_MODULE(); 

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

- (void)doMyAction { 
    [self sendEventWithName:@"onEvent" body:@""]; 
} 

@end 
0

RNNotification *通知= [RNNotification allocWithZone:nilを]; [notification sendNotificationToReactNative]私は上記のすべてを試して、それを私のアプリで動作させることができませんでした。

最後にthisが私のために働いた。一見する機能

RNNotification *notification = [RNNotification allocWithZone: nil]; 
[notification sendNotificationToReactNative] 
関連する問題