RN与IOS原生双向通信以及UI绑定通信的使用方式
Posted 乍的
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RN与IOS原生双向通信以及UI绑定通信的使用方式相关的知识,希望对你有一定的参考价值。
react-native提交给ios客户端数据来实现通信或者交互有2种方式:
1、双向通信的方式:
RN to IOS
原生端:
#import <React/RCTBridgeModule.h>
@implementation RNToNativeEmitter
RCT_EXPORT_MODULE(RNToNativeEmitter);
RCT_EXPORT_METHOD(showText:(NSString *)textValue) textHeight:(CGFloat)height
{
dispatch_async(dispatch_get_main_queue(), ^{
//在主线程种接受并处理数据
...
});
}
RN端:
import { NativeModules } from \'react-native\';
//RNToNativeEmitter为OC的类名称,showText是OC宏注册的方法名称
NativeModules.RNToNativeEmitter.showText(\'显示的文本\', 200);
IOS to RN
原生端:
NativeToRNEmitter.h:
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@interface NativeToRNEmitter : RCTEventEmitter <RCTBridgeModule>
NativeToRNEmitter.m:
- (NSArray<NSString *> *)supportedEvents {
return @[@"EmitterMsg"];//注册的RN的方法名称
}
//注册本地通知来实现在其他模块中调用sendEventWithName的方法
-(void)beginObserving
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(emitEventInternal:)
name:@"EmitterMsg"
object:nil];
}
-(void)endObserving
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)emitEventInternal:(NSNotification *)notification
{
[self sendEventWithName:@"EmitterMsg"
body:notification.userInfo];
}
OC在需要的地方调用:
[[NSNotificationCenter defaultCenter] postNotificationName:@"EmitterMsg"
object:self
userInfo:@{}];
RN接收端:
import { NativeEventEmitter } from \'react-native\';
var messager = new NativeEventEmitter(NativeToRNEmitter);
messager.addListener("EmitterMsg", (result) => {
//result为上个代码快中userInfo参数的字典对象
});
2、UI绑定通信的方式
原生端:
首先创建一个继承于UIView的CategoryView(举栗子)类,这个类有如下功能:
1、有一个成员方法-(void)showCategoryName:(NSString*)textValue
;
2、内部渲染了一个RCTView的RN对象。
CategoryViewManager.h(类名为目标对象的UIView对象名称+Manager)
#import <React/RCTViewManager.h>
@interface CategoryViewManager: RCTViewManager
CategoryViewManager.m
@interface CategoryViewManager()
@property (nonatomic, strong) CategoryView *cView;
@end
@implementation CategoryViewManager
RCT_EXPORT_MODULE()
//创建目标UIView的实例
- (UIView *)view {
self.cView = [[CategoryView alloc] initWithFrame:CGRectZero];
return self.cView;
}
RCT_EXPORT_METHOD(showCategoryName:(nonnull NSNumber *)reactTag textValue:(nonnull NSString*)textValue) {
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
CategoryView *view = viewRegistry[reactTag];//从注册的CategoryView集合中获取实例
if(view&&[view isKindOfClass:[CategoryView class]]){
[view showCategoryName:textValue];
}
}];
}
@end
RN端:
首先一个组件类用于映射到原生组件
import { requireNativeComponent, findNodeHandle, UIManager } from \'react-native\';
const CategoryView = requireNativeComponent(\'CategoryView\', Category);//CategoryView与IOS端类名一致
class Category extends PureComponent {
sendTextValue2Native(textValue) {
//CategoryView与IOS端类名一致,showCategoryName方法名与RCT_EXPORT_METHOD注册的方法名称保持一致
UIManager.dispatchViewManagerCommand(
findNodeHandle(this),
UIManager.getViewManagerConfig(\'CategoryView\').Commands.showCategoryName,
[textValue]//此处参数对应原生showCategoryName方法的参数,从第二个开始
);
}
render() {
return <CategoryView>
<View>
{this.props.children}
</View>
</CategoryView>;
}
}
export default Category;
如何使用:
import { Category } from \'local/Category\';
<Category ref={ref => { this.categoryRef = ref }}>
<TouchableWithoutFeedback onPress={() => {
this.categoryRef.sendTextValue2Native(\'测试文本\')
}}>
...
</TouchableWithoutFeedback>;
<Category />
这样在Category组件时,原生同样就会创建一个原生CategoryView的实例对象。这样在RN端调用sendTextValue2Native就可以将内容发送到原生的showCategoryName方法,然后在原生处理相关的逻辑。文章中的调用还是较为简单,涉及到属性等更复杂的使用可以参考文章:https://reactnative.cn/docs/n...
总结:
2种通信方式应用的场景是不一样的,第一种双向通信使用相对更加普遍,因为通信编写方式与2端不会有太多代码上的耦合度,第二种方式相对来说就和UI的使用绑定结合的更紧密,限制也更多一些~
以上是关于RN与IOS原生双向通信以及UI绑定通信的使用方式的主要内容,如果未能解决你的问题,请参考以下文章