天天看點

react native 內建人臉識别 --ios

上一篇介紹了 android 端的內建

這篇介紹下ios的內建.

整體思路和android類似:ios原生這邊內建sdk後,寫個ios和RN的互動類,暴露給RN ,RN再調用 跳轉人臉識别頁。成功,或失敗 内部sdk中有回調,通過ios這邊監聽的觸發 通知RN 成功或失敗。

react native 內建人臉識别 --ios

image.png

1.sdk的內建。

2.ios和RN的互動

  1. sdk的內建:

    按照文檔,把sdk 拷貝到工程目錄,然後add files 到工程中。

    react native 內建人臉識别 --ios

按文檔要求配置,導入相關的資源檔案,架包等,新版的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 發消息吧:

首先我們同樣建一個互動類,名字可以随便取,便于了解就行。

react native 內建人臉識别 --ios

.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();
  }
           
react native 內建人臉識别 --ios

相關列印結果

ok,到這裡整個流程成功了。感謝幫助過我的原生大佬飛哥,踩過RN和ios互動坑的 阿木木 。希望這篇文章能對大家有點用吧,少走點彎路.... 同時有錯誤的地方也可以指出來,謝謝!

繼續閱讀