上一篇介绍了 android 端的集成
这篇介绍下 ios 的集成.
整体思路和 android 类似: ios 原生这边集成 sdk 后, 写个 ios 和 RN 的交互类, 暴露给 RN ,RN 再调用 跳转人脸识别页. 成功, 或失败 内部 sdk 中有回调, 通过 ios 这边监听的触发 通知 RN 成功或失败.
image.png
1.sdk 的集成.
2.ios 和 RN 的交互
sdk 的集成:
按照文档, 把 sdk 拷贝到工程目录, 然后 add files 到工程中.
image.png
按文档要求配置, 导入相关的资源文件, 架包等, 新版的 Xcode 在我们 导入 sdk 的时候回自动添加 这些相关资源.
集成之后 就是 ios 原生这边写方法跳转到这个人脸识别页面, 然后把这个方法暴露给 RN 去调用.
2.1 这里着重介绍下 RN 和 ios 的交互.
首先我们在工程中新建一个类 如何新建可参考 简书中有介绍过 ios 的. h .m 文件
然后. h 文件 去实现 "RCTBridgeModule" 协议的 Objective-C 类
- #import <Foundation/Foundation.h>
- #import <React/RCTBridgeModule.h>
- #import <React/RCTLog.h>
- @interface testRn : NSObject <RCTBridgeModule>
- @end
.m 文件 官网是这样说的: 为了实现 RCTBridgeModule 协议, 你的类需要包含 RCT_EXPORT_MODULE() 宏. 这个宏也可以添加一个参数用来指定在 Javascript 中访问这个模块的名字. 如果你不指定, 默认就会使用这个 Objective-C 类的名字.
- @implementation testRn
- RCT_EXPORT_MODULE(test); // 这里可以填写 模块的名字 不写的话默认类名
- // 给 Javascript 导出的方法 这个方法有几个参数 RN 那边调用的时候就传几个参数要不然会报错. 用不到传参 也可以不写.
- RCT_EXPORT_METHOD(start:(NSString *)name location:(NSString *)location)
- {
- // 这里触发人脸识别跳转
- // 具体怎么跳转官方发的 sdk 的 demo 都有些, 拷贝进来修改下就行了
- }
- @end
到这里 RN 调用原生已经可以了, 接下来就是 监听识别成功或失败的回调, 告诉 RN.
2.2 这里就叫 ios 给 RN 发消息吧:
首先我们同样建一个交互类, 名字可以随便取, 便于理解就行.
image.png
.h 文件
- #import <Foundation/Foundation.h>
- #import <React/RCTBridgeModule.h>
- #import <React/RCTLog.h>
- #import <React/RCTBridge.h>
- #import <React/RCTEventEmitter.h>
- @interface EventEmitterManager : RCTEventEmitter <RCTBridgeModule>
.m 文件
- #import "EventEmitterManager.h"
- @interface EventEmitterManager()
- @end
- NSString *const kEventEmitterManagerEvent = @"EventEmitterManagerEvent";
- @implementation EventEmitterManager
- - (instancetype)init
- {
- self = [super init];
- if (self) { // 新增监听 有多个监听就写多个 return 的时候返回多个
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiMethd:) name:@"CallBackMsg" object:nil];
- }
- return self;
- }
- RCT_EXPORT_MODULE() // 把方法导出给 RN 没有就默认类名
- - (void)notiMethd:(NSNotification *)notiMethd
- {
- NSDictionary *resultDic = notiMethd.userInfo;
- NSString *base64Encoded = resultDic[@"base64Encoded"];
- NSString *key = resultDic[@"key"];
- [self sendEventWithName:@"CallBackMsg" body:@{@"base64Encoded":base64Encoded,@"key":key}]; // 发消息给 RN
- }
- - (NSArray<NSString *> *)supportedEvents {
- return @[@"CallBackMsg"]; // 如果有多个监听 这里加上例如: return @[@"CallBackMsg",@"CallBackMsg2"];
- }
- @end
其他模块触发监听:
- // 注意: 监听的名字要一致, 成功之后不要忘记关闭当前页
- // 触发 ios 监听
- [[NSNotificationCenter defaultCenter] postNotificationName:@"CallBackMsg" object:nil userInfo:@{@"base64Encoded":@"",@"key":@"success"}];
- // 关闭当前页面
- [self dismissViewControllerAnimated:YES completion:nil];
ios 这边的方法我们已经写好了, 下面看下 RN 这边如何使用
- import {
- Platform,
- NativeEventEmitter,
- NativeModules,
- DeviceEventEmitter,
- } from 'react-native';
- ..........
- componentDidMount() {
- let EventEmitterManager = NativeModules.EventEmitterManager;
- let eventEmitterManagerEmitter = new NativeEventEmitter(
- EventEmitterManager,
- );
- this.reciveIosMsg = eventEmitterManagerEmitter.addListener(
- 'CallBackMsg',
- result => {
- if (result.key === 'success' && result.base64Encoded != '') {
- // 做相关成功处理
- }
- })
- }
- componentWillUnmount() {// 删除监听
- this.reciveIosMsg.remove();
- }
相关打印结果
ok, 到这里整个流程成功了. 感谢帮助过我的原生大佬飞哥, 踩过 RN 和 ios 交互坑的 阿木木 . 希望这篇文章能对大家有点用吧, 少走点弯路.... 同时有错误的地方也可以指出来, 谢谢!
来源: http://www.jianshu.com/p/05d9a8b43be4