您如何使用 React Native 正确地从桥接 iOS 模块到 JavaScript 发出和接收事件?
How do you properly emit and receive an event from a bridged iOS module to JavaScript using React Native?
我有一个 React Native 应用程序,想从 Obj-C 调度一个事件来测试应用程序 event/emitting 系统的工作方式。我已经阅读了所有文档,翻阅了 react native repo 以获取示例,但仍然不知道我的代码有什么问题。
我知道我的 Obj-C 会触发,因为我已经逐步完成 Xcode 中的代码并且 self.bridge.eventDispatcher
不是 nil
。我还知道,通过控制台日志,在模拟器中呈现的主要 React Native 组件已安装并呈现。问题是我没有看到任何这些通知的任何控制台输出。可能是我错误地要求 ApplicationManager
class,或者订阅了错误的 "thing" 来监听事件。可能我正在做很多事情 incorrectly/poorly :-)
这是我的 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
我知道这些事件和通知已经在 RCTAppState
中可用,但我正在尝试自己推出一个解决方案来学习:
我都尝试过使用:
[self.bridge.eventDispatcher sendAppEventWithName:name body:body];
和:
[self.bridge.eventDispatcher sendDeviceEventWithName:name body:body];
没有任何成功。除了接收者 class 用于 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)} );
},
调试器行在 Chrome 调试器中命中并且 NativeAppEventEmitter
不是 undefined
,而是:
NativeAppEventEmitter
EventEmitter {_subscriber: EventSubscriptionVendor}_subscriber:
EventSubscriptionVendor__proto__: EventEmitter
我的猜测是我做错了什么,但我不知道是什么。任何帮助将不胜感激。
您订阅事件的代码和发送事件的代码都没有问题。
您遇到的问题是因为 ApplicationDidFinishLaunching
事件在您订阅事件的 componentDidMount
之前触发。
我有一个 React Native 应用程序,想从 Obj-C 调度一个事件来测试应用程序 event/emitting 系统的工作方式。我已经阅读了所有文档,翻阅了 react native repo 以获取示例,但仍然不知道我的代码有什么问题。
我知道我的 Obj-C 会触发,因为我已经逐步完成 Xcode 中的代码并且 self.bridge.eventDispatcher
不是 nil
。我还知道,通过控制台日志,在模拟器中呈现的主要 React Native 组件已安装并呈现。问题是我没有看到任何这些通知的任何控制台输出。可能是我错误地要求 ApplicationManager
class,或者订阅了错误的 "thing" 来监听事件。可能我正在做很多事情 incorrectly/poorly :-)
这是我的 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
我知道这些事件和通知已经在 RCTAppState
中可用,但我正在尝试自己推出一个解决方案来学习:
我都尝试过使用:
[self.bridge.eventDispatcher sendAppEventWithName:name body:body];
和:
[self.bridge.eventDispatcher sendDeviceEventWithName:name body:body];
没有任何成功。除了接收者 class 用于 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)} );
},
调试器行在 Chrome 调试器中命中并且 NativeAppEventEmitter
不是 undefined
,而是:
NativeAppEventEmitter
EventEmitter {_subscriber: EventSubscriptionVendor}_subscriber:
EventSubscriptionVendor__proto__: EventEmitter
我的猜测是我做错了什么,但我不知道是什么。任何帮助将不胜感激。
您订阅事件的代码和发送事件的代码都没有问题。
您遇到的问题是因为 ApplicationDidFinishLaunching
事件在您订阅事件的 componentDidMount
之前触发。