目录
- 1)搭建-原生集成rn
- 2)demo
- 3)访问原生侧常量
- 4)访问原生侧方法
- 4.1)void无返回
- 4.2)有返回回调
- 5)原生启动RN并获取ViewController传递的数据
- 6)原生发送通知给RN
1)搭建-原生集成rn
- react-native init 工程名
- copy原iOS工程至Rn工程/ios中
- 进入ios目录,配置CocoaPods依赖
~/ios/
pod init
- 修改生成的Podfile文件
~/ios/Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'studyRn_Native_iOS' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for studyRn_Native_iOS
# 'node_modules'目录一般位于根目录中
# 但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
#'CxxBridge', # 如果RN版本 >= 0.45则加入此行
'DevSupport', # 如果RN版本 >= 0.43,则需要加入此行才能开启开发者菜单
'RCTText',
'RCTNetwork',
'RCTWebSocket', # 这个模块是用于调试功能的
# 在这里继续添加你所需要的RN模块================
]
# 如果你的RN版本 >= 0.42.0,则加入下面这行
pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
# 如果RN版本 >= 0.45则加入下面三个第三方编译依赖
#pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
#pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
#pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
end
- 安装pod包
~/ios/
pod install
pod安装完成
-
打开studyRn_Native_iOS.xcworkspace进入xcode
打开xcode -
在ViewController中导入头文件,并修改入口代码
#import "ViewController.h"
#import <React/RCTRootView.h>
@interface ViewController ()
@end
@implementation ViewController
- (IBAction)onClick:(id)sender {
//如果这样写 需要RN侧有 index.js的入口文件
// NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
//如果这样写 需要RN侧有 index.ios.js的入口文件
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.127:8081/index.ios.bundle"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL : jsCodeLocation
moduleName : @"FirstReactComponent"
initialProperties :
@{
@"scores" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions : nil];
UIViewController *vc = [[UIViewController alloc] init];
vc.view = rootView;
[self presentViewController:vc animated:YES completion:nil];
}
- 新建RN-Component
export default class FirstReactComponent extends Component {
render() {
const data = this.props.scores;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
大家好,我是React界面
</Text>
{
data.map(function(item,index){
return (
<Text style={styles.welcome} key={index}>
大家好,我是{item.name},我今年{item.value}岁
</Text>
)
})
}
</View>
);
}
}
- 在RN的入口文件处注册此Component,注意:所有暴露给原生的Component都需要在入口文件处注册。
~/index.ios.js
import FirstReactComponent from './src/FirstReactComponent';
...
//暴露给原生使用
AppRegistry.registerComponent('FirstReactComponent', () => FirstReactComponent);
- 打开Packager服务
~/工程根目录
npm start
RN集成iOS
- 生产打release包
//release包流程
//第一步 新建release_ios文件夹 然后
//react-native bundle --entry-file index.ios.js --platform ios --dev false --bundle-output release_ios/main.jsbundle --assets-dest release_ios/
//第二步 将assets和main.jsbundle拖进xcode [create floder references即可]
//为了方便使用,也可以把打包命令写到npm script中
//package.json中 "bundle-ios":"node node_modules/react-native/local-cli/cli.js bundle --entry-file index.ios.js --platform ios --dev false --bundle-output release_ios/main.jsbundle --assets-dest release_ios/"
//运行命令直接打包 npm run bundle-ios
//最后
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
2)demo
ios屏幕快照RN屏幕快照
demo
- 新建原生桥接模块MyNativeBridgeModule
// MyNativeBridgeModule.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface MyNativeBridgeModule : NSObject<RCTBridgeModule>
@end
// MyNativeBridgeModule.m
#import "MyNativeBridgeModule.h"
@implementation MyNativeBridgeModule
RCT_EXPORT_MODULE();
-(NSDictionary *)constantsToExport
{
return @{
@"Native_Constants_A": @"原生常量A",
@"Native_Constants_B": @"原生常量B",
};
}
RCT_EXPORT_METHOD(NATIVE_sendDataToNative:(NSString *)str){
NSLog(@"收到RN侧的str数据:%@",str);
}
RCT_EXPORT_METHOD(NATIVE_sendDataToNativeCallback:(NSDictionary *)dict callback:(RCTResponseSenderBlock)callback){
for (NSString *key in dict) {
NSLog(@"收到RN侧的dict数据: key= %@, value= %@", key,dict[key]);
}
NSString *str = @"数据已收到,且被我改变啦";
callback(@[[NSNull null],str]);
}
@end
- RN侧文件
export default class FirstReactComponent_Home extends Component {
constructor(props) {
super(props);
this.state = {
name:'大家好,我是React界面'
};
}
_sendDataToNative=()=>{
NativeModules.MyNativeBridgeModule.NATIVE_sendDataToNative('我是来自RN的数据');
};
_sendDataToNativeCallback=()=>{
const params = {
'姓名':'杰洛特',
'性别':'男',
}
NativeModules.MyNativeBridgeModule.NATIVE_sendDataToNativeCallback(
params,
(error,result)=>{
this.setState({
name:result
})
}
)
};
render() {
const data = this.props.scores;
const Native_Constants_A = NativeModules.MyNativeBridgeModule.Native_Constants_A;
return (
<View style={styles.container}>
{
data.map(function(item,index){
return (
<Text style={styles.welcome} key={index}>
我是Intent数据:{item.name},{item.value}岁
</Text>
)
})
}
<Text style={styles.welcome}>
{Native_Constants_A}
</Text>
<TouchableOpacity onPress={this._sendDataToNative} style={styles.button}>
<Text style={styles.instructions}>
点击发送数据给原生
</Text>
</TouchableOpacity>
<Text style={styles.welcome}>
{this.state.name}
</Text>
<TouchableOpacity onPress={this._sendDataToNativeCallback} style={styles.button}>
<Text style={styles.instructions}>
点击发送数据给原生,并回调修改
</Text>
</TouchableOpacity>
</View>
);
}
}
//暴露给原生使用
AppRegistry.registerComponent('FirstReactComponent', () => FirstReactComponent);
3)访问原生侧常量
在MyNativeBridgeModule中
-(NSDictionary *)constantsToExport
{
return @{
@"Native_Constants_A": @"原生常量A",
@"Native_Constants_B": @"原生常量B",
};
}
RN侧只需调用即可
const Native_Constants_A = NativeModules.MyNativeBridgeModule.Native_Constants_A;
4)访问原生侧方法
- 4.1)void无返回
RCT_EXPORT_METHOD(NATIVE_sendDataToNative:(NSString *)str){
NSLog(@"收到RN侧的str数据:%@",str);
}
_sendDataToNative=()=>{
NativeModules.MyNativeBridgeModule.NATIVE_sendDataToNative('我是来自RN的数据');
};
- 4.2)有返回回调
RCT_EXPORT_METHOD(NATIVE_sendDataToNativeCallback:(NSDictionary *)dict callback:(RCTResponseSenderBlock)callback){
for (NSString *key in dict) {
NSLog(@"收到RN侧的dict数据: key= %@, value= %@", key,dict[key]);
}
NSString *str = @"数据已收到,且被我改变啦";
callback(@[[NSNull null],str]);
}
_sendDataToNativeCallback=()=>{
const params = {
'姓名':'杰洛特',
'性别':'男',
}
NativeModules.MyNativeBridgeModule.NATIVE_sendDataToNativeCallback(
params,
(error,result)=>{
this.setState({
name:result
})
}
)
};
5)原生启动RN并获取ViewController传递的数据
- (void)viewDidLoad {
[super viewDidLoad];
//如果这样写 需要RN侧有 index.js的入口文件
// NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
//如果这样写 需要RN侧有 index.ios.js的入口文件
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.127:8081/index.ios.bundle"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL : jsCodeLocation
moduleName : @"FirstReactComponent"
initialProperties :
@{
@"datas" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions : nil];
self.view = rootView;
}
const data = this.props.datas;
6)原生发送通知给RN
~ NativeBridge.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
//继承了RCTEventEmitter这个类,用来发送通知的
@interface NativeBridge : RCTEventEmitter<RCTBridgeModule>
@end
~ NativeBridge.m
@implementation NativeBridge
RCT_EXPORT_MODULE();
//实现suppportEvents方法
- (NSArray<NSString *> *)supportedEvents
{
return @[@"Native_PushTo_RN_AliPayBoardcast"];
}
//设置发送事件通知给RN侧,通知规约为 "Native_PushTo_RN_AliPayBoardcast"
- (void)AliPayBoardcastReceived:(NSNotification *)notification
{
[self sendEventWithName:@"Native_PushTo_RN_AliPayBoardcast" body:notification.object];
}
- 本例中实现调用支付宝支付,支付宝回调给AppDelegate
新增单例方法,注册native本地通知,当AppDelegate接收到支付宝的回调时,发送通知给本地通知,由本地通知调用方法通知RN侧
~ NativeBridge.m
+ (id)allocWithZone:(NSZone *)zone {
static NativeBridge *pushManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
pushManager = [super allocWithZone:zone];
//注册通知alipay支付宝回调
[[NSNotificationCenter defaultCenter] addObserver:pushManager selector:@selector(AliPayBoardcastReceived:) name:@"AliPayBoardcast" object:nil];
});
return pushManager;
}
~AppDelegate.m
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
[[NSNotificationCenter defaultCenter] postNotificationName:@"AliPayBoardcast" object:resultDic];
}];
return YES;
}
}
参考资料
官网
网友评论