ReactNative与原生Objective-C交互

RN项目引用三方:
RN三方库需要npm 导入
这里是官网地址:
添加库:
进入RN项目根目录:
输入命令:npm install “第三方库” –save 如:npm install react-native-swiper –save
删除库:
如果没有–save只是删除库,不会删除依赖
输入命令 npm uninstall “第三方库” –save [npm uninstall react-native-toast –save]

RN项目与原生交互:
首先建立Manager管理类并引入如下文件
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher>
#import <React/RCTEventEmitter >
解释下这几个头文件:
RCTEventDispatcher(事件调度器)
RCTBridge (桥接)
RCTBridgeModule (桥接模块)需要循序协议如:
@interface XXXXManger : NSObject<RCTBridgeModule>
RCTEventEmitter (RCT的事件源)
Log就不用说了

XXXXManger.m中添加RCT_EXPORT_MODULE()宏,来 实现RCTBridgeModule协议。这个宏也可以添加一个参数用来指定在Javascript中访问这个模块的名字。如果你不指定,默认就会使用这个Objective-C类的名字。
RCT_EXPORT_METHOD 支持所有标准JSON类型,包括:
string (NSString)
number (NSInteger, float, double, CGFloat, NSNumber)
boolean (BOOL, NSNumber)
array (NSArray) 包含本列表中任意类型
object (NSDictionary) 包含string类型的键和本列表中任意类型的值
function (RCTResponseSenderBlock)

如何提供方法供调用?我给点实际的代码以简单的版本号为例代码如下:
OC代码接口提供:
RCT_EXPORT_METHOD(getSVersion:(RCTResponseSenderBlock)callBack){
      NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
      callBack(@[[NSNull null],build]);
}

Javascript里可以这样调用这个方法:
import { NativeModules } from 'react-native';
var XXXXManger = NativeModules. XXXXManger;
XXXXManger.getSVersion((error,events) =>{
console.log('error', error);
console.log('events', events);
});
有些人自然要问反过来OC调用RN如何实现?
OC调用RN就简单了通知:
[self.bridge.eventDispatcher sendAppEventWithName:@"didReceiveNotification" body:userInfo];
是很不是很熟悉? 跟iOS的Notification太像了
sendAppEventWithName:@"didReceiveNotification" body:userInfo
postNotificationName:@"hidenTabbar" object:body
这里没什么说的我们继续
另外sendAppEventWithName已经过期但还能使用,现在需要将OC调用RN与RN调用CO分开处理上述方法可用一个Manager管理现在分开,自定义类并继承 RCTEventEmitter.h( #import <React>)遵循RCTBridgeModule协议
然后要导出你所有的方法名字
-(NSArray<NSString> *)supportedEvents
{
return @[@"isCallback", @"xxxx", @"xxxxxx"];//有几个就写几个
实现你导出的所有方法,里面都使用 sendEventWithName 方法即可

-(void)iseCallback:(NSString)code result:(NSString) result {
[self sendEventWithName:@"iseCallback"
body:@{
@"code": code,
@"result": result, }];
继续使用sendAppEventWithName:会警告
'sendDeviceEventWithName:body:' is deprecated: Subclass RCTEventEmitter instead
Javascript里可以这样调用这个方法:
import {
...
NativeModules,
NativeEventEmitter, //导入NativeEventEmitter模块
} from 'react-native';

var XXXXManger = NativeModules. XXXXManger;
//在组件中使用
componentWillMount() {
this.listener = NativeEventEmitter.addListener('isCallback', this.isCallback.bind(this)); //对应了原生端的名字
}
componentWillUnmount() {
this.listener && this.listener.remove(); //记得remove哦
this.listener = null;
}
这里说下 EventEmitter 有三种类型
sendAppEventWithName

sendDeviceEventWithName

sendInputEventWithName

相对应的Javascript里也有三种类型

RCTAppEventEmitter

RCTDeviceEventEmitter

RCTInputEventEmitter

互相调用已经到此为止了:
再来说说RN的界面如何显示OC界面:
引入头文件
#import<React/RCTViewManager.h>
并继承RCTViewManager
添加宏 RCT_EXPORT_MODULE()
重写 - (UIView *)view {
return view;
}
你有可能会用到枚举类型那么你应该导入一下头文件并做如下操作
#import <React/RCTConvert.h>
@implementation RCTConvert(XXXXX)

RCT_ENUM_CONVERTER(XXXXX, (@{
@"XXXXX1": @(XXXXX1),
@"XXXXX2": @(XXXXX2),
@"XXXXX3": @(XXXXX3),
}), XXXXX1, unsignedLongLongValue)
//#define RCT_ENUM_CONVERTER(type, values, default, getter) //facebook 实现代码//
@end

  • (NSDictionary *) xxxxx {
    return @{@"XXXXX1":@(XXXXX1),
    @"XXXXX2":@(XXXXX2),
    @"XXXXX3":@(XXXXX3)};
    }

RCT_EXPORT_VIEW_PROPERTY(xxxxx, XXXXX);
这样在Javascript里就可以用枚举类型了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容