RN調用原生
需要原生定義個類實現(xiàn)<RCTBridgeModule>
協(xié)議糕非,比如
@interface BoxModule : NSObject<RCTBridgeModule>
@end
然后再m文件中實現(xiàn)桩撮,需要注意的是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
實現(xiàn)RCTBridgeModule
協(xié)議:
#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文件實現(xiàn):
#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秒出現(xiàn)打印信息,說明原生可以正常調用RN方法并傳遞參數(shù)了:
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' }