在React Native iOS中监听事件

雅各布·帕特纳德

我一生无法获得一个事件,该事件可以从iOS本机正确地跨网桥发送到react本机JS上下文。在Objective-C方面,我希望有一个模块可以轻松地通过桥发送事件。我将此类称为EventEmitter,其定义如下:

// 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]

因此,我可以告诉我同时发送了带有标签blah的应用程序事件和设备事件,并且我已注册使用DeviceEventEmitter和NativeAppEventEmitters监听blah事件,但没有在监听器中被调用。

我究竟做错了什么??谢谢阅读!

哈利卜

我已经尝试调度事件,但是bridge当您EventEmitter使用手动创建新实例,似乎未初始化[EventEmitter alloc] init]

您应该让react-native创建实例。我检查了本机组件,它们正在使用-(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;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章