博客> RN与原生的交互
RN与原生的交互
2018-09-24 11:12 评论:0 阅读:266 cvl556
ReactNative与Objective-C相互调用

RN项目引用三方: RN三方库需要npm 导入 这里是官网地址: 添加库: 进入RN项目根目录: 输入命令:npm install “第三方库” –save 如:npm install react-native-swiper –save 删除库: 如果没有–save只是删除库,不会删除依赖 输入命令 npm uninstall “第三方库” –save [npm uninstall react-native-toast –save]

RN项目与原生交互: 首先建立Manager管理类并引入如下文件

import

#import <React>
#import <React>
#import <React>
#import <React>
解释下这几个头文件:
RCTEventDispatcher(事件调度器)
RCTBridge (桥接)
RCTBridgeModule (桥接模块)需要循序协议如:

@interface XXXXManger : NSObject RCTEventEmitter (RCT的事件源) Log就不用说了

XXXXManger.m中添加RCT_EXPORT_MODULE()宏,来 实现RCTBridgeModule协议。这个宏也可以添加一个参数用来指定在Javascript中访问这个模块的名字。如果你不指定,默认就会使用这个Objective-C类的名字。
RCT_EXPORT_METHOD 支持所有标准JSON类型,包括:
string (NSString)
number (NSInteger, float, double, CGFloat, NSNumber)
boolean (BOOL, NSNumber)
array (NSArray) 包含本列表中任意类型
object (NSDictionary) 包含string类型的键和本列表中任意类型的值
function (RCTResponseSenderBlock)

如何提供方法供调用?我给点实际的代码以简单的版本号为例代码如下:
OC代码接口提供:
RCT_EXPORT_METHOD(getSVersion:(RCTResponseSenderBlock)callBack){
      NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
      callBack(@[[NSNull null],build]);
}

Javascript里可以这样调用这个方法: import { NativeModules } from 'react-native'; var XXXXManger = NativeModules. XXXXManger; XXXXManger.getSVersion((error,events) =>{ console.log('error', error); console.log('events', events); }); 有些人自然要问反过来OC调用RN如何实现? OC调用RN就简单了通知: [self.bridge.eventDispatcher sendAppEventWithName:@"didReceiveNotification" body:userInfo]; 是很不是很熟悉? 跟iOS的Notification太像了 sendAppEventWithName:@"didReceiveNotification" body:userInfo postNotificationName:@"hidenTabbar" object:body 这里没什么说的我们继续 另外sendAppEventWithName已经过期但还能使用,现在需要将OC调用RN与RN调用CO分开处理上述方法可用一个Manager管理现在分开,自定义类并继承 RCTEventEmitter.h( #import )遵循RCTBridgeModule协议 然后要导出你所有的方法名字 -(NSArray *)supportedEvents { return @[@"isCallback", @"xxxx", @"xxxxxx"];//有几个就写几个 实现你导出的所有方法,里面都使用 sendEventWithName 方法即可

-(void)iseCallback:(NSString)code result:(NSString) result { [self sendEventWithName:@"iseCallback" body:@{ @"code": code, @"result": result, }]; 继续使用sendAppEventWithName:会警告 'sendDeviceEventWithName:body:' is deprecated: Subclass RCTEventEmitter instead Javascript里可以这样调用这个方法: import { ... NativeModules, NativeEventEmitter, //导入NativeEventEmitter模块 } from 'react-native';

var XXXXManger = NativeModules. XXXXManger; //在组件中使用 componentWillMount() { this.listener = NativeEventEmitter.addListener('isCallback', this.isCallback.bind(this)); //对应了原生端的名字 } componentWillUnmount() { this.listener && this.listener.remove(); //记得remove哦 this.listener = null; } 这里说下 EventEmitter 有三种类型 sendAppEventWithName

sendDeviceEventWithName

sendInputEventWithName

相对应的Javascript里也有三种类型

RCTAppEventEmitter

RCTDeviceEventEmitter

RCTInputEventEmitter

互相调用已经到此为止了: 再来说说RN的界面如何显示OC界面: 引入头文件 #import<React> 并继承RCTViewManager 添加宏 RCT_EXPORT_MODULE() 重写 - (UIView *)view { return view; } 你有可能会用到枚举类型那么你应该导入一下头文件并做如下操作 #import <React> @implementation RCTConvert(XXXXX)

RCT_ENUM_CONVERTER(XXXXX, (@{ @"XXXXX1": @(XXXXX1), @"XXXXX2": @(XXXXX2), @"XXXXX3": @(XXXXX3), }), XXXXX1, unsignedLongLongValue) //#define RCT_ENUM_CONVERTER(type, values, default, getter) //facebook 实现代码// @end

  • (NSDictionary *) xxxxx { return @{@"XXXXX1":@(XXXXX1), @"XXXXX2":@(XXXXX2), @"XXXXX3":@(XXXXX3)}; }

RCT_EXPORT_VIEW_PROPERTY(xxxxx, XXXXX); 这样在Javascript里就可以用枚举类型了。

收藏
0
sina weixin mail 回到顶部