前提:此篇屬於調用原生SDK功能進行認證後,返回給RN端進行結果展示。
目前想調用第三方(某圖場景)的活體識別,但是官網明明寫着,有 H5 的方式,但是提供的 SDK 只有原生的,所以需要調原生,並且是在原生中調用三方的檢測頁面,然後回調結果給 RN。
總體的思路:
如下圖所示,我們的核心點在於對 RCT 的單例設計以及回調的使用。
總體的步驟:
1,RN 頁面引入 NativeModules
2,編寫原生橋接頁面(這裏橋接 RN 頁面與三方活體識別頁面)
3,原生三方活體識別頁面返回值
4,RN 頁面展示結果
那麼,讓我們準備好 Xcode ,coffee 加上耳機開搞吧。
一,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 文件,命名如下:
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 中調用的方法名,在這裏調用 resolve 或 reject,即進入了 Promise 的回調,但是我們是用於第三方頁面獲取參數後再進行回調,所以要把當前 View 單例化,把其傳遞給第三方頁面進行處理回調,就 ok 啦。(例子的話,稍後閒下來再補上吧),這裏可以看到,我把其傳遞給了第三方頁面 OliveappLivenessDetectionViewController(這是友方廠商的sdk,故只貼部分代碼,請看步驟三)
三,三方頁面調用
在這裏調用單例的對象的成功方法,回調給 RN 頁面即可。
四,RN 頁面展示結果
和第一步一樣的,只是在成功後,跳轉到下一頁面。
總結一下就是,RN編寫頁面 -> 原生編寫 ->(若調原生第三方頁面,則需要把原生的對象單例化傳遞)-> 處理後調用 resolve 或 reject