上篇文章文章链接写了RN集成到本地项目并成功运行,这篇写两者间的交互
首先说明一点,两者间的互调都是通过通知中心(NSNotificationCenter)实现的
一、RN调用原生(Native)
新建一个类(作用类似于桥接文件)RNToNativeBridgeModule,继承NSObject,实现RCTBridgeModule协议
RNToNativeBridgeModule.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface RNToNativeBridgeModule : NSObject<RCTBridgeModule>
@end
RNToNativeBridgeModule.m
#import "RNToNativeBridgeModule.h"
#import <React/RCTBridge.h>
@implementation RNToNativeBridgeModule
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE(RNToNativeBridgeModule);//不加参数也可以,默认导出本身
RCT_EXPORT_METHOD(RNToNative:(NSString *)msg) { //RN中调用RNToNative:此处响应
dispatch_async(dispatch_get_main_queue(), ^{ //要在主线程发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"RNToNative" object:msg];
});
}
@end
index.ios.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
NativeModules,
} from 'react-native';
var RNToNativeBridgeModule = NativeModules.RNToNativeBridgeModule;
export default class RNAndiOS extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity activeOpacity={0.5} onPress={() => RNToNativeBridgeModule.RNToNative('测试一下')}>
<Text style={styles.welcome}>
点我测试RN调Native!
</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
AppRegistry.registerComponent('RNAndiOS', () => RNAndiOS);
SecondViewController中添加通知
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"RNAndiOS" initialProperties:nil launchOptions:nil];
rootView.backgroundColor = [UIColor whiteColor];
rootView.frame = CGRectMake(0, isIphoneX?88:64, KMainScreenW, isIphoneX?KMainScreenH-122:KMainScreenH-64);
[self.view addSubview:rootView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doNotification:) name:@"RNToNative" object:nil];
}
- (void)doNotification:(NSNotification *)notification {
NSLog(@"%@",notification.object);//rn中的参数
[self.navigationController popViewControllerAnimated:YES];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"RNToNative" object:nil];
}
iPhone X截图,测试点击会返回上一级:
![](https://img.haomeiwen.com/i2287077/a4bfc89ddc5c3a2b.png)
Simulator Screen Shot - iPhone X - 2017-11-20 at 16.23.57.png
二、原生(Native)调用RN
与RN调用原生类似,新建一个继承自RCTEventEmitter的类NativeToRNBridgeModule,实现RCTBridgeModule协议
NativeToRNBridgeModule.h
#import <React/RCTEventEmitter.h>
//定义一个宏方便调用,如果调用多个方法多个方法名参数,几个方法就会对应几个通知
#define RNIOSExportJsToReact(noti) [[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted" object:noti];
@interface NativeToRNBridgeModule : RCTEventEmitter<RCTBridgeModule>
@end
NativeToRNBridgeModule.m
#import "NativeToRNBridgeModule.h"
@implementation NativeToRNBridgeModule
RCT_EXPORT_MODULE() //不加参数默认导出本身
- (NSArray<NSString *> *)supportedEvents { //所有需要调用的方法名
return @[@"NativeToRN"];
}
- (void)startObserving {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(emitEventInternal:)
name:@"event-emitted"
object:nil];
}
- (void)stopObserving {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)emitEventInternal:(NSNotification *)notification
{
// 向RN发送消息,body可以是string,dictionary等
[self sendEventWithName:@"NativeToRN" body:notification.object];
}
+ (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted"
object:self
userInfo:payload];
}
@end
index.ios.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
NativeModules,
NativeEventEmitter
} from 'react-native';
var RNToNativeBridge = NativeModules.RNToNativeBridgeModule;
var NativeToRNBridge = NativeModules.NativeToRNBridgeModule;
const Emitter = new NativeEventEmitter(NativeToRNBridge);
export default class RNAndiOS extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity activeOpacity={0.5} onPress={()=>RNToNativeBridge.RNToNative('测试一下下')}>
<Text style={styles.welcome}>
点我测试RN调Native
</Text>
</TouchableOpacity>
</View>
)
}
componentWillMount() {
Emitter.addListener('NativeToRN',(body)=>this._getNotice(body));
}
_getNotice (body) {
alert("这是RN弹窗\n" + body);
// this.forceUpdate();
}
componentWillUnMount() {
this.subScription.remove();
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
AppRegistry.registerComponent('RNAndiOS', () => RNAndiOS);
最后在SecondViewController随便加一个按钮调用即可
- (void)sendMsgToRN {
RNIOSExportJsToReact(@"body");
}
全文结束,这是学习RN很基础的东西,但对刚开始学习的小伙伴来说也很蛋疼。有帮助的话请点个赞。
网友评论