ReactNative与原生(IOS)页面跳转和通信(一))

2020-01-07  本文已影响0人  冲云简

序言: React Native无论是在社区和应用程度上,在国内外是十分广泛和普及的。最近总结了下RN关于IOS和Android的通信,希望大家喜欢,文章末尾有github的Demo地址。本文参照官网来写:地址跳转

RCT_EXPORT_METHOD 支持所有标准 JSON 类型,包括:

除此以外,任何RCTConvert类支持的的类型也都可以使用(参见RCTConvert了解更多信息)。RCTConvert还提供了一系列辅助函数,用来接收一个 JSON 值并转换到原生 Objective-C 类型或类。

下面看代码:
原生实现:
xxx.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
///添加RCTBridgeModule协议
@interface LiveModule : NSObject<RCTBridgeModule>

@end

xxx.m ——实现导出给JavaScript的方法。包含Callback和Promise回调

@implementation LiveModule

RCT_EXPORT_MODULE();

///直接调用原生方法
RCT_EXPORT_METHOD(pushLiveViewController: (NSString *)str) {
  ///rn和原生桥接是异步的,所以需要对UI操作必须在主线程。
  dispatch_async(dispatch_get_main_queue(), ^{
    UINavigationController *nav = (UINavigationController *)AppDelegate.shareAppDelegate.window.rootViewController;
    ViewController *vc = [[ViewController alloc] init];
    [nav presentViewController:vc animated:false completion:nil];
  });
}

///callback回调
RCT_EXPORT_METHOD(findEvents: (RCTResponseSenderBlock)callback) {
  callback(@[[NSNull null], CALL_VALUE]);
}

///promise回调
RCT_EXPORT_METHOD(liveValue: (BOOL)valueI
                  findEventsWithResolver: (RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
  
  if (valueI == YES) {
    resolve(PROMISE_VALUE);
  }else {
    NSError *error = nil;
    reject(@"error", @"This is error!", error);
  }
}

JavaScript通过NativeModules调用原生方法

const liveModule = NativeModules.LiveModule;
///直接调用
liveModule.pushLiveViewController('xxx');

//callback方式
liveModule.findEvents((error, value) => {
      this.setState({
        callText: value,
      });
    });

//promise方式
liveModule
      .liveValue(true)
      .then(value => {
        this.setState({
          promiseText: value,
        });
      })
      .catch(error => {
        console.log(error);
      });

原生给JavaScript发送事件
最好的方法是继承RCTEventEmitter,实现suppportEvents方法并调用self sendEventWithName:。

@interface LiveEventEmitter : RCTEventEmitter <RCTBridgeModule>
///给js端发送事件
- (void)sendMessageToRN: (NSDictionary *)dict eventName:(NSString *)name;
@end
@interface LiveEventEmitter()

@property(nonatomic, strong)NSArray * nameArrays;
@end

@implementation LiveEventEmitter
RCT_EXPORT_MODULE();

/// 重写方法,添加事件名
-(NSArray<NSString *> *)supportedEvents {
  return self.nameArrays;
}
//重写方法,单例获取bridge。如果不重写bridge为nil
+ (id)allocWithZone:(struct _NSZone *)zone {
  static LiveEventEmitter *live = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    live = [super allocWithZone:zone];
  });
  
  return live;
}

///发送事件给js
- (void)sendMessageToRN: (NSDictionary *)dict eventName:(NSString *)name {
  [self sendEventWithName:name body:dict];
}

- (NSArray *)nameArrays {
  if (_nameArrays == nil) {
    _nameArrays = @[@"EventName"];
  }
  return _nameArrays;
}

@end

JavaScript订阅事件

//在componentDidMount()中订阅事件
const eventEmitter = new NativeEventEmitter(NativeModules.LiveEventEmitter);
      this.listener = eventEmitter.addListener('EventName', value => {
        this.setState({
          touchText: value.message,
        });
      });

Demo地址https://github.com/JoyceRao/React-Native-RNNativeCommunication

参考链接https://www.jianshu.com/p/ea3484f54643

上一篇下一篇

猜你喜欢

热点阅读