reactnative~ios模块通信混合跳转方案详解
Rn~ios模块混合通信跳转方案详解
ios > rn
指定页面跳转
在原生接入rn文章中说了,原生接入rn其实是在原生页面上显示包装后的视图。
原生嵌入RN一般会遇到有多个跳转RN的地方,而且跳转到不同模块中去,这个可以通过初始化RCTRootView的时候配置:
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions;
用过initialProperties把配置参数传到js的props中,然后,加载js时候可以根据配置参数进行加载渲染不同的页面
ios2targetrn.pngrn > ios
上面说过从原生到rn的跳转,但是怎么返回呢?:
1:如果是用的统一导航栏(push方式),那默认导航栏即可。
2:但是rn模块,作为独立模块,还是要有自己的导航容器。所以,这种就需要有自己的返回事件处理。
无回调通信
1.第一步 在iOS工程里面创建一个对象RNToNativeManager 并遵循RCTBridgeModule协议(需要引入#import <React/RCTBridgeModule.h>)
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
@interface RNToNativeManaer : NSObject<RCTBridgeModule>
@end
2.第二步 在.m文件需要包含RCT_EXPORT_MODULE()宏,而且要在RCT_EXPORT_METHOD这个宏里面跑出来供javaScript调用的方法()(注意如果要在这个方法里面操作view要回到主线程)
#import "RNToNativeManaer.h"
@implementation RNToNativeManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(testMethod:(NSString *)content {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter]postNotificationName:@"push" object:nil];
});
});
@end
3.第三步 在js端调用native跑出来的这个方法(这里要引入NativeModules)
1: import {NativeModules} from 'react-native';
2: var RNToNativeManager = NativeModules.RNToNativeManager;
3: RNToNativeManager.testMethod('xxx');
在这里要注意: Javascript方法名
导出到Javascript的方法名是Objective-C的方法名的第一个部分。React Native还定义了一个RCT_REMAP_METHOD()宏,它可以指定Javascript方法名。当许多方法的第一部分相同的时候用它来避免在Javascript端的名字冲突。且桥接到Javascript的方法返回值类型必须是void。
注意
上面说的RNToNativeManager,只是把原生~rn桥接处理提出来了。原生接入rn中也说了,rn入口其实就是承载在原生页面上的,所以,关于桥接这块当然也可以直接写到宿主页面上。重点是第一步遵守RCTBridgeModule,到第3步js才能获取到原生模块,不然程序都跑步起来。vscode运行看不出错误。xcode运行能看到运行错误:
reason: 'RnToNativeManager does not conform to the RCTBridgeModule protocol'
回调函数通信
回调函数RCTResponseSenderBlock,它可以把返回值传给javaScript. 逻辑就是rn调用native暴露的方法,之后nvtive回调给rn。结合ios中block回调理解即可。rn传匿名函数给native,native调用函数块,块代码是在rn中执行的。
RCT_EXPORT_METHOD(testMethod:(RCTResponseSenderBlock)callBack){
NSArray *array =@[@"1",@"2"];
callBack(@[[NSNull null],array, xxx]);
//callBack 入参rn跟原生约定好就行
}
rn端代码
如下处理就可以了
RNToNativeManaer.findEvents((error,events)=>{
if (error){
console.log(error);
}else {
console.log(events);
this.setState({
event:events,
});
console.log(xxx);
}
//callBack 入参rn跟原生约定好就行
});
rn 跳转指定原生页面
上面说过了rn~原生间的通信。就是rn通过调用原生模块暴露出来的方法进行通信。另外,rn是依附在原生页面上的,所以,只要rn能将信息通讯到原生,所有的处理就都可以做了。例如:rn跳转到原生,就是rn宿主vc跳转到另一个vc。所以,rn调用native暴露的跳转方法就行了