如何使用React Native正确地从桥接的iOS模块发出和接收事件到JavaScript?

Aar*_*ron 3 javascript facebook bridge objective-c react-native

我有一个React Native应用程序,并希望从Obj-C发送一个事件来测试应用程序事件/发射系统的工作方式.我已经阅读了所有文档,翻阅了本地回购的示例以了解示例,但仍然不知道我的代码有什么问题.

我知道我的Obj-C会触发,因为我已经在Xcode中逐步完成了代码,但事实self.bridge.eventDispatcher并非如此nil.我还知道,通过控制台日志,模拟器中呈现的主要React Native组件会安装并呈现.问题是我没有看到任何这些通知的控制台输出.我可能会ApplicationManager错误地要求这个类,或者订阅错误的"东西"来监听事件.我可能做错很多/很差的事情:-)

这是我的Obj-C导出模块:

@implementation ApplicationManager

RCT_EXPORT_MODULE();

@synthesize bridge = _bridge;

- (instancetype)init {
  self = [super init];
  if ( self ) {
    NSNotificationCenter * notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(applicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
  }

  return self;
}

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

- (void)applicationDidEnterBackground:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationDidEnterBackground" body:nil];
}

- (void)applicationWillEnterForeground:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationWillEnterBackground" body:nil];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationDidFinishLaunching" body:nil];
}

- (void)applicationDidBecomeActive:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationDidBecomeActive" body:nil];
}

- (void)applicationWillResignActive:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationWillResignActive" body:nil];
}

- (void)applicationDidReceiveMemoryWarning:(NSNotification *)notification {
  [self dispatchAppEventWithName:@"ApplicationDidReceiveMemoryWarning" body:nil];
}

- (void)dispatchAppEventWithName:(NSString *)name body:(NSDictionary *)body {
  [self.bridge.eventDispatcher sendAppEventWithName:name body:body];
}

@end
Run Code Online (Sandbox Code Playgroud)

我知道这些事件和通知已经可用RCTAppState,但我正在尝试自己解决一个解决方案来学习:

https://github.com/facebook/react-native/blob/2f6e7336cb96bf14d47554ae0db1836075ea809e/React/Modules/RCTAppState.m

我尝试过使用两者:

[self.bridge.eventDispatcher sendAppEventWithName:name body:body];
Run Code Online (Sandbox Code Playgroud)

和:

[self.bridge.eventDispatcher sendDeviceEventWithName:name body:body];
Run Code Online (Sandbox Code Playgroud)

没有任何成功.除了用于JavaScript端调度事件的接收者类之外,我不确定这两种方法之间的区别.

这是相关的React Native代码:

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TabBarIOS,
  NativeAppEventEmitter,
} = React;

// ... other code omitted for brevity ... 

componentDidMount: function() {
    console.log("main component didMount");
    debugger;
    NativeAppEventEmitter.addListener("ApplicationDidFinishLaunching", (reminder) => { console.log("app event emitter: ApplicationDidFinishLaunching:", reminder)} );
 },
Run Code Online (Sandbox Code Playgroud)

调试器行在Chrome调试器中命中,而NativeAppEventEmitter不是undefined,而是:

NativeAppEventEmitter
EventEmitter {_subscriber: EventSubscriptionVendor}_subscriber:
EventSubscriptionVendor__proto__: EventEmitter
Run Code Online (Sandbox Code Playgroud)

我的猜测是我做错了什么,但我不知道是什么.任何帮助将不胜感激.

小智 5

订阅事件的代码和发送事件的代码很好.

您遇到的问题是因为ApplicationDidFinishLaunching事件componentDidMount在您订阅事件之前被触发.