RN调用原生
需要原生定义个类实现<RCTBridgeModule>
协议,比如
@interface BoxModule : NSObject<RCTBridgeModule>
@end
然后再m文件中实现,需要注意的是RCT_EXPORT_METHOD默认是在异步线程
调用的,切记牵扯到UI操作需要回到主线程:
RCT_EXPORT_METHOD(goBack){
//这里可以找到当前的viewController的navigationController进行pop操作
}
在RN文件中import { NativeModules, } from 'react-native';
引入后,调用下面代码即可调用到原生中:
NativeModules.BoxModule.goBack();
如果我们需要在RN中从原生读取一个Token:
// 获取token
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getToken)
{
NSString *token = [[NSUserDefaults standardUserDefaults]objectForKey:@"token"];
return token;
}
在RN中这么调用:
NativeModules.BoxModule.getToken();
原生调用RN
新建类BoxEventManager
类继承自RCTEventEmitter
实现RCTBridgeModule
协议:
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
NS_ASSUME_NONNULL_BEGIN
@interface BoxEventManager : RCTEventEmitter<RCTBridgeModule>
- (void)sendUserMap:(NSDictionary *)obj;
@end
NS_ASSUME_NONNULL_END
.m文件实现:
#import "BoxEventManager.h"
@implementation BoxEventManager
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents
{
return @[@"userMap"];
}
- (void)sendUserMap:(NSDictionary *)obj
{
[self sendEventWithName:@"userMap" body:obj];
}
+(id)allocWithZone:(NSZone *)zone {
static BoxEventManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
@end
在RN中使用:
import { Text, View, NativeEventEmitter, NativeModules, SafeAreaView ,StatusBar} from 'react-native'
import React, { Component } from 'react'
const { BoxEventManager } = NativeModules;
const boxEmitter = new NativeEventEmitter(BoxEventManager);
export class Box extends Component {
componentDidMount() {
console.log('加载了')
boxEmitter.addListener(
'userMap',
(reminder) => {
console.log('接收到信息了')
console.log(reminder)
}
);
}
//需要销毁
componentWillUnmount() {
console.log('销毕了')
const subscription = this.subscription;
if (!subscription) return;
subscription.remove()
}
render() {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={{height:600,alignItems:'center',justifyContent:'center',backgroundColor:0xffffff}}>
<View>
<Text style={{fontSize:200,color: 0xff0000}}>Box</Text>
</View>
</SafeAreaView>
</>
)
}
}
export default Box
我们可以在iOS工程里didFin中加入代码:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
BoxEventManager *event = [[BoxEventManager alloc] init];
[event sendUserMap:@{@"123":@"456"}];
});
运行iOS工程后5秒出现打印信息,说明原生可以正常调用RN方法并传递参数了:
2023-06-25 17:37:09.399405+0800 boxRn[49176:625878] [javascript] 加载了
2023-06-25 17:37:14.111064+0800 boxRn[49176:625878] [javascript] 接收到信息了
2023-06-25 17:37:14.114189+0800 boxRn[49176:625878] [javascript] { '123': '456' }
网友评论