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    
 
 
 
posted @ 2017-06-01 15:56  努力努力再努力吧  阅读(1849)  评论(0编辑  收藏  举报