React Native - iOS Native 给JS 发送事件通知

即使没有被JavaScript调用,原生模块也可以给JavaScript发送事件通知。最好的方法是继承RCTEventEmitter,重写supportedEvents方法并调用[self sendEventWithName:]

OC 实现如下

RNNotificationManager.h

#import 
#import 
#import 
@interface RNNotificationManager : RCTEventEmitter 
@end

RNNotificationManager.m


#import "RNNotificationManager.h"

NSString *const kEventEmitterManagerEvent  = @"EventEmitterManagerEvent";

@implementation RNNotificationManager

RCT_EXPORT_MODULE()

// RN组件 发送事件通知
RCT_EXPORT_METHOD(postNotificationEvent:(NSString *)name)
{
    RCTLogInfo(@"postNotificationEvent->:%@",name);
    [self sendEventWithName:kEventEmitterManagerEvent body:name];
}
// 导出常量
- (NSDictionary *)constantsToExport {
    return @{ @"Myconstant": kEventEmitterManagerEvent,};
}

/**
 * Override this method to return an array of supported event names.
 * Attempting to observe or send an event that isn't included in this list will result in an error.
 * 重写此方法,返回支持的事件名称的数组。
 *
 * 试图观察或发送不包含在该列表中的事件,将导致错误。
 * RCTEventEmitter 会检查 supportedEvents 并只发送支持的事件
 */
- (NSArray *)supportedEvents {
    return @[kEventEmitterManagerEvent,];
}
@end

也有如下这种方式调用的,可能是没有继承RCTEventEmitter,没有测试,可参考测试一下。

  // 将消息转发到JS中
  [self.bridge.eventDispatcher sendAppEventWithName:@"testNotification" body:@{@"name": eventName}];

在JS中接收OC发送过来的通知

import { NativeEventEmitter, NativeModules } from 'react-native';

class RNTalk extends Component {

  componentWillMount(){
    // 拿到原生模块
    var EventEmitterManager = NativeModules.RNNotificationManager;
      
    // 创建自定义事件接口
    const eventEmitterManagerEmitter = new NativeEventEmitter(EventEmitterManager);
      
    // 导出常量
    const EventEmitterManagerEvent  = EventEmitterManager.Myconstant;
      
    // 监听原生 接收原生发来的通知
    /**
     * addListener函数
     * 第一个参数要和OC方法中的name参数相同,
     * 第二个函数参数的参数为OC方法中的body。
     * 所以OC需要传递给JS的数据通过body来传输。
     */ 
    this.listener = eventEmitterManagerEmitter.addListener(
      EventEmitterManagerEvent,
      (data) => {console.log('通知来了-->'+data)}
    );
  }
  // 别忘了取消订阅,通常在componentWillUnmount生命周期方法中实现。
  componentWillUnmount(){
    this.listener.remove();
  }
  //发送通知
  _postNotification(){
    var EventEmitterManager = NativeModules.RNNotificationManager;
      // 调用原生模块 postNotificationEvent方法  发送通知消息
      EventEmitterManager.postNotificationEvent('张杨事件传递');
  }

  render() {
    return (
      
        this._postNotification()}>
        发送通知
        
      
    );
  }
}

同OC中的通知一样,JS中的通知使用完毕后也要进行释放,同样一般写在视图被释放的时候。

 componentWillUnmount(){
    this.listener.remove();
  }

优化无监听处理的事件

如果你发送了一个事件却没有任何监听处理,则会因此收到一个资源警告。要优化因此带来的额外开销,你可以在你的RCTEventEmitter子类中覆盖startObserving和stopObserving方法。

@implementation CalendarManager
{
  bool hasListeners;
}

// 在添加第一个监听函数时触发
-(void)startObserving { 
    hasListeners = YES;
    // Set up any upstream listeners or background tasks as necessary
}

// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving { 
    hasListeners = NO;
    // Remove upstream listeners, stop unnecessary background tasks
}

- (void)calendarEventReminderReceived:(NSNotification *)notification
{
  NSString *eventName = notification.userInfo[@"name"];
  if (hasListeners) { // Only send events if anyone is listening
    [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
  }
}

你可能感兴趣的:(React Native - iOS Native 给JS 发送事件通知)