原生iOS给RN传值

2019-11-07  本文已影响0人  米开朗骑騾

ios端:

创建类继承 RCTEventEmitter类并遵守RCTBridgeModule协议

.h文件

#import <React/RCTEventEmitter.h>

#define StopDrawingEventEmitter(noti) [[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted" object:noti];

@interface StopDrawingEventEmitter : RCTEventEmitter <RCTBridgeModule>

//伸出方法方便调用 也可不写 外部可直接发通知
+ (void)callBackRNData:(NSMutableDictionary *)data;

- (void)callBackMethod:(NSDictionary *)data;

@end

.m文件

#import "StopDrawingEventEmitter.h"

@implementation StopDrawingEventEmitter

RCT_EXPORT_MODULE()

/// 重写方法,定义支持的事件集合
- (NSArray<NSString *> *)supportedEvents {
  return @[@"CustomEventName"]; //这里返回的将是你要发送的消息名的数组。
}

+ (id)allocWithZone:(struct _NSZone *)zone {
  static StopDrawingEventEmitter *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}

- (instancetype)init {
  self = [super init];
  if (self) {
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter removeObserver:self];
    [defaultCenter addObserver:self
                      selector:@selector(sendCustomEvent:)
                          name:@"sendCustomEventNotification"
                        object:nil];
  }
  return self;
}

1.
/// 接收通知的方法,接收到通知后发送事件到RN端。RN端接收到事件后可以进行相应的逻辑处理或界面跳转
- (void)sendCustomEvent:(NSNotification *)notification {
  [self sendEventWithName:@"CustomEventName" body:notification.object[@"dic"]];
}

2.
//伸出方法供调用 内部调用通知 
+ (void)callBackRNData:(NSDictionary *)data{
  [[NSNotificationCenter defaultCenter] postNotificationName:@"sendCustomEventNotification" object:data];
}

3.
//直接向RN传值 不知安全不安全 没考虑监听一直开启状态
- (void)callBackMethod:(NSDictionary *)data{
  [self sendEventWithName:@"CustomEventName" body:data[@"dic"]];
}

@end

使用对象方法时需注意:

RCT_EXPORT_MODULE()

/// 重写方法,定义支持的事件集合
- (NSArray<NSString *> *)supportedEvents {
  return @[@"routeEvent",@"distanceEvent"]; //这里返回的将是你要发送的消息名的数组。
}

- (void)callBackRNData_routeEvent:(NSString *)routeEventArr{
  [self sendEventWithName:@"routeEvent" body:routeEventArr];
}

- (void)callBackRNData_distanceEvent:(NSMutableArray *)distanceEventArr{
  [self sendEventWithName:@"distanceEvent" body:distanceEventArr];
}

+ (id)allocWithZone:(struct _NSZone *)zone {
  static eventEmitterModule *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}

//allocWithZone 不写会导致下面崩溃 至于allocWithZone的作用
/**因为 [[self alloc] init]; 调用时,会默认调用+(id)allocWithZone:(NSZone*)zone方法的,原来allocWithZone:(NSZone
*)zone是在给对象** eventEmitterModule
分配内存空间了。其**中**zone** 可以想象成一个内存池,alloc,allocWithZone或是dealloc这些操作,都是在这个内存池中操作的。cocoa总是会配置一个默认的NSZone,任何默认的内存操作都是在这个“zone”上操作的。默认的NSZone的缺陷在于,它是全局范围的,时间一长,必然会导致内存的碎片化,如果你需要大量的alloc一些object,那么性能就会受到一些影响。所有cocoa提供方法,你可以自己生成一个NSZone(实际上就是我上面的demo那样,重写allocWithZone方法就行了),并将alloc,
copy全部限制在这个”zone“之内。*/
image.png

某个页面按钮或方法调用

//引入头文件
#import "StopDrawingEventEmitter.h"

//某个方法传值 
RCT_EXPORT_METHOD(startAndStop:(nonnull NSNumber *)reactTag type:(NSString *)type) {

//直接发通知
//    [[NSNotificationCenter defaultCenter] postNotificationName:@"sendCustomEventNotification" object:@"1111"];

//调用伸出的方法
    [StopDrawingEventEmitter callBackRNData:@{@"dic":@"111"}];

//对象方法调用
StopDrawingEventEmitter *stop = [[StopDrawingEventEmitter alloc] init];
    [stop callBackMethod:@{@"dic":@"111"}];

}

RN方面:

引入
{
    NativeModules,
    NativeEventEmitter,
}

const StopDrawingEventEmitter = NativeModules.StopDrawingEventEmitter

//注册监听
componentDidMount() {
        let eventEmitter = new NativeEventEmitter(StopDrawingEventEmitter);
        this.listener = eventEmitter.addListener("CustomEventName", (result) => {
            alert("获取到事件通知" + result);
        })

    }

componentWillUnMount() {
        //移除监听

        this.listener && this.listener.remove();
    }

参考:
https://blog.csdn.net/xiangzhihong8/article/details/75092576
https://blog.csdn.net/sinat_17775997/article/details/80702729
https://blog.csdn.net/qq_30970529/article/details/53606199

调用原生 startAndStop 方法 请看上一篇文章

上一篇 下一篇

猜你喜欢

热点阅读