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 <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher>
#import <React/RCTEventEmitter >
解释下这几个头文件:
RCTEventDispatcher(事件调度器)
RCTBridge (桥接)
RCTBridgeModule (桥接模块)需要循序协议如:
@interface XXXXManger : NSObject<RCTBridgeModule>
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 <React>)遵循RCTBridgeModule协议
然后要导出你所有的方法名字
-(NSArray<NSString> *)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.h>
并继承RCTViewManager
添加宏 RCT_EXPORT_MODULE()
重写 - (UIView *)view {
return view;
}
你有可能会用到枚举类型那么你应该导入一下头文件并做如下操作
#import <React/RCTConvert.h>
@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里就可以用枚举类型了。
网友评论