react与原生交互有点类似于ios中的webview与h5交互,交互都需要有一端先发起交互请求,然后才能双方交互,当然ios第一次加载(webview或rn页面)也算交互请求那么总是ios端先发起交互请求,如果不算,那么都是其他端发起交互请求可以是传值,可以是监听函数.比如:rn端要给ios传值,那么react端必须监听ios中的某一个类中的某一个函数才能发起交互.如果ios想向react交互,目前我所了解的没有直接的ios到react的方法,都是迂回折中的办法,比如:rn->ios->rn模式,rn先发送一个广播通知给ios端,ios接受到广播以后再将广播通知发送给rn端.也就是ios想直接与rn交互(调用函数,或传值)都是rn端先发起然后ios端接受到发起请求确认了再与ios交互
一句话概括:ios端是御姐有点高冷总是被动被人(rn端/h5端)调用然后她才能响应你给你传情.
1.rn传值/调用原生 callback模式(双方交互)
os端代码
第一步导入
#import <React/RCTBridgeModule.h>并且遵守RCTBridgeModule协议
第二步
//导出模块,不添加参数即默认为该类的类名名
RCT_EXPORT_MODULE();
第三步//有2个参数第一个参数为rn端传过来的值(rn->ios先调戏),具体要什么类型的协商,第二个参数为callback为rn传值以后的回掉都懂得我们可以在这里面给rn端传值(ios->rn然后她响应你给你传值)
其中doSomething就是媒介(类似于电话号码/生份证)rn端就是通过它来调戏ios端的
RCT_EXPORT_METHOD(doSomething:(NSString *)testStr callback:(RCTResponseSenderBlock)callback){
NSLog(@"rn传过来的参数为%@",testStr);
if (testStr.length>0) {
NSString *OsStr = @"我是ios端传给你的值";
callback(@[[NSNull null],OsStr]);
}
}
rn端代码
//给ios传值
var NativeTest = require('react-native').NativeModules.AppDelegate;
//给原生传值,并且原生返回值给rn端(item.title是rn端flatlist中的itme的标题,(error,events是接受ios端回调)
NativeTest.doSomething(item.title,(error,events)=>{
if(error) {
console.error(error);
}else{
alert(events);
}
});
2:rn端页面push到原生界面
(也许有些人认为这有什么难的在上面的函数中添加跳转方法不就行了吗,告诉你不行,因为我也是这么认为的,但是项目中正真用的时候懵逼了发现根本push不了贴下方法)
RCT_EXPORT_METHOD(doSomething:(NSString *)testStr callback:(RCTResponseSenderBlock)callback){
NSLog(@"rn传过来的参数为%@",testStr);
if (testStr.length>0) {
//解决Xcode9.0线程错误提示,虽然不在主线程调用不报错可以运行但是还是加上吧
dispatch_async(dispatch_get_main_queue(), ^{
//rn端触发跳转到原生界面
[self PushTwoVc];
});
}
}
**
rn触发跳转到原生界面
*/
-(void)PushTwoVc{
NSLog(@"我被rn触发来现在我要跳转到原生界面中去喽");
//ios中的rn界面点击rn按钮跳转到原生界面
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
TwoViewController *twoVC = [[TwoViewController alloc]init];
//其中app.nav是viewcontroller根视图
[app.nav pushViewController:twoVC animated:YES];
}
//在appDelegate.h文件中添加
@property (nonatomic, strong) UINavigationController *nav;
_nav = [[UINavigationController alloc]initWithRootViewController:rootViewController];
self.window.rootViewController = _nav;
rn端调用创建iosui组件:同理
-(void)ConFigNativeView{
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIView *v = [[UIView alloc]initWithFrame:CGRectMake(100, 100,100,100)];
v.backgroundColor = [UIColor redColor];
[app.nav.view addSubview:v];
}
结论
:rn与ios交互总是rn端先发起交互请求然后ios被动相应,我们可以通过上面的原理可以有很大的操作控件,比如rn端需要用到支付宝支付,但是支付宝还不支持rn端,那么我可以在ios端接入,rn端调用的模式.想想是不是有点小激动呢,哈哈开始行动起来吧.少年