前提:此篇属于调用原生SDK功能进行认证后,返回给RN端进行结果展示。


目前想调用第三方(某图场景)的活体识别,但是官网明明写着,有 H5 的方式,但是提供的 SDK 只有原生的,所以需要调原生,并且是在原生中调用三方的检测页面,然后回调结果给 RN。


总体的思路:

如下图所示,我们的核心点在于对 RCT 的单例设计以及回调的使用

android native react 和原生页面 reactnative调用原生sdk_RN 调用 iOS 第三方sdk


总体的步骤:

1,RN 页面引入 NativeModules

2,编写原生桥接页面(这里桥接 RN

3,原生三方活体识别页面返回值

4,RN 页面展示结果

那么,让我们准备好 Xcodecoffee 加上耳机开搞吧。


一,RN 页面引入 NativeModules

这里很简单

import { NativeModules } from 'react-native';

var FaceRecognition = NativeModules.FaceRecognition;
// 参数为 projectId 以及 hostUrl,Promise 的调用方法
FaceRecognition.startFaceRecognition(projectId, hostUrl)
    .then((msg) => {
          msg = JSON.stringify(msg);
          if (msg.includes('checkPass')){
             this.props.navigator.push({
             id: 'ContractList',
             comp: ContractList,
              param: {
                      ...this.props.param,
              }});
           }else{
              //alert('对比失败,请重试!');
           }
          }).catch((error) => {
              //alert('活体检测对比失败,请重试!');
     });

FaceRecognition 以及为什么是调用 startFaceReconition ,请看第二步


 二,编写原生桥接页面(桥接 RN 页面与三方活体识别页面)

这里建议用 Xcode 打开,以便有相对应的代码提示及着色。

分别创建 .h.m 文件,命名如下:

android native react 和原生页面 reactnative调用原生sdk_RN调用iOS_02

FcaReconition.h:

//
//  FaceRecognition.h
// 
//
//  Created by supervons on 2019/2/27.
//  Copyright © 2019年 Facebook. All rights reserved.
//

#import "RCTViewManager.h"
#import <UIKit/UIKit.h>
#import "RCTBridgeModule.h"

// 继承 RN 方法
@interface FaceRecognition : RCTViewManager
// promise 成功回调
@property (nonatomic, retain) RCTPromiseResolveBlock resolve;
// promise 失败回调
@property (nonatomic, retain) RCTPromiseRejectBlock reject;
// 接受的两个参数
@property (nonatomic, retain) NSString *projectId;
@property (nonatomic, retain) NSString *hostUrl;

// 用于在第三方页面调用该实例回调
+ (id)sharedInstance;

+ (id)allocWithZone:(NSZone *)zone;

+ (id)copyWithZone:(struct _NSZone *)zone;

+ (id)mutableCopyWithZone:(struct _NSZone *)zone;

@end

FcaReconition.m:

//
//  FaceRecognition.m
//  rzzl
//
//  Created by supervons on 2019/2/27.
//  Copyright © 2019年 Facebook. All rights reserved.
//

#import "FaceRecognition.h"
#import "OliveappLivenessDetectionViewController.h"
#import <Foundation/Foundation.h>
#import "AppDelegate.h"
#import "RCTBridge.h"

@implementation FaceRecognition{
  
  // 默认的识别成功的回调
  void (^_successHandler)(id);
  // 默认的识别失败的回调
  void (^_failHandler)(NSError *);
}
static FaceRecognition * _instance = nil;
static bool isFirstAccess = YES;

RCT_EXPORT_MODULE()
#pragma 生命周期相关方法

RCT_EXPORT_METHOD(startFaceRecognition:(NSString *) projectId hostUrl:(NSString *) hostUrl resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject)
{
  //获取projectId与hostUrl
  self.projectId = projectId;
  self.hostUrl = hostUrl;
  //以下样例代码展示了如何初始化活体检测
  UIStoryboard * board = [UIStoryboard storyboardWithName:@"LivenessDetection" bundle:nil];
  OliveappLivenessDetectionViewController * livenessViewController;
  livenessViewController = (OliveappLivenessDetectionViewController*) [board instantiateViewControllerWithIdentifier: @"LivenessDetectionStoryboard"];

  //初始化参数
  //FaceRecognition* inst = [FaceRecognition sharedInstance];
  self.resolve = resolve;
  self.reject = reject;
  __weak typeof(self) weakSelf = self;
  NSError *error;
  BOOL isSuccess;
  isSuccess = [livenessViewController setConfigLivenessDetection: weakSelf withError: &error];
  
  //弹出活体检测界面,可用show,push
  UIViewController* curVc = [FaceRecognition getCurrentViewController];
  dispatch_async(dispatch_get_main_queue(), ^{
  [curVc presentViewController:livenessViewController
                     animated:YES
                   completion:^{
                     [[UIApplication sharedApplication] endIgnoringInteractionEvents];
                   }];
  });
}

@end

 这里的核心方法是 RCT_EXPORT_METHOD,可以看到第一个参数 startFaceRecognition 即为 RN 中调用的方法名,在这里调用 resolvereject,即进入了 Promise 的回调,但是我们是用于第三方页面获取参数后再进行回调,所以要把当前 View 单例化,把其传递给第三方页面进行处理回调,就 ok 啦。(例子的话,稍后闲下来再补上吧),这里可以看到,我把其传递给了第三方页面 OliveappLivenessDetectionViewController(这是友方厂商的sdk,故只贴部分代码,请看步骤三)


三,三方页面调用

android native react 和原生页面 reactnative调用原生sdk_#import_03

在这里调用单例的对象的成功方法,回调给 RN 页面即可。 


四,RN 页面展示结果

android native react 和原生页面 reactnative调用原生sdk_桥接_04

和第一步一样的,只是在成功后,跳转到下一页面。


 总结一下就是,RN编写页面 -> 原生编写 ->(若调原生第三方页面,则需要把原生的对象单例化传递)-> 处理后调用 resolvereject