iOS 原生模块 给 Javascript(ReactNative) 发送事件 (通知监听)
官方中文文档是这样描述的:
就给我们这几句话 就打发我们了。
按照上面的写法,根本不知道
- (void)calendarEventReminderReceived:(NSNotification *)notification 方法 什么时候去调用。
但是我们根据iOS知识,知道想要发送通知,肯定要先监听通知。
所以我们要保证RN组件 先监听事件通知,在去原生组件发送事件通知。
原生组件:
EventEmitterManager.h
#import <React/RCTBridgeModule.h> #import <React/RCTEventEmitter.h> @interface EventEmitterManager : RCTEventEmitter <RCTBridgeModule> @end
EventEmitterManager.m
#import "EventEmitterManager.h" #import <React/RCTEventDispatcher.h> #import <React/RCTLog.h> NSString *const kEventEmitterManagerEvent = @"EventEmitterManagerEvent"; @implementation EventEmitterManager //@synthesize bridge = _bridge; RCT_EXPORT_MODULE(); // 等 RN组件 监听事件通知后 在发送事件通知 RCT_EXPORT_METHOD(postNotificationEvent:(NSString *)name) { RCTLogInfo(@"postNotificationEvent->:%@",name); [self sendEventWithName:kEventEmitterManagerEvent body:name]; } - (NSDictionary<NSString *, NSString *> *)constantsToExport { return @{ @"EventEmitterManagerEvent": kEventEmitterManagerEvent, }; } - (NSArray<NSString *> *)supportedEvents { return @[kEventEmitterManagerEvent,]; } @end
RN组件:
componentWillMount(){ // 拿到原生模块 var EventEmitterManager = NativeModules.EventEmitterManager; // 创建自定义事件接口 const eventEmitterManagerEmitter = new NativeEventEmitter(EventEmitterManager); // 导出常量 const EventEmitterManagerEvent = EventEmitterManager.EventEmitterManagerEvent; // 监听原生 发送的通知 this.listener = eventEmitterManagerEmitter.addListener( EventEmitterManagerEvent, (data) => Alert.alert('来了 来了 ->'+ data) ); } componentDidMount() { var EventEmitterManager = NativeModules.EventEmitterManager; // 调用原生模块 postNotificationEvent方法 EventEmitterManager.postNotificationEvent('张杨事件传递'); } componentWillUnmount(){ this.listener.remove(); }
可以看到
componentWillMount 中 先监听通知
componentDidMount 中 再调用原生模块方法去发送通知
componentWillUnmount 中 再去移除监听
还有一个小Tip:
我在写demo时候 不想一直 在 index.ios.js 中 去添加其他组件,然后RCTRootView去实例化。
所以我就投机一下,
- (IBAction)postNotification:(id)sender {
_jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"src/PostNotification" fallbackResource:nil];
_rootView = [[RCTRootView alloc] initWithBundleURL : _jsCodeLocation
moduleName : @"PostNotification"
initialProperties : nil
launchOptions : nil];
UIViewController *vc = [[UIViewController alloc] init];
vc.view = _rootView;
[self.navigationController pushViewController:vc animated:YES];
}
bundleRoot 写路径 src/PostNotification