首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >iOS 端人脸核身接入全流程,含常见报错处理

iOS 端人脸核身接入全流程,含常见报错处理

原创
作者头像
hollyx
发布于 2026-09-30 16:15:00
发布于 2026-09-30 16:15:00
600
举报

摘要:

iOS 端集成人脸核身 SDK,除了常规的库导入和权限配置,还有几个编译选项容易踩坑。本文按接入顺序梳理完整流程,给出详细的代码示例,并整理常见报错的处理方式。


一、环境要求

  • 开发环境:Xcode 11.0 或以上
  • 支持系统:iOS 9.0 及以上
  • 语言:Objective-C 或 Swift

二、两种集成方式

2.1 手动接入方式

步骤 1:导入 Framework

在 Xcode 中,选择 Target → Build Phases → Link Binary With Libraries,添加以下框架:

代码语言:txt
复制
└── HuiYanPublicSDK.framework
步骤 2:导入资源文件

在 Copy Bundle Resources 中添加:

资源类型

文件

说明

模型文件

face-tracker-v003.bundle

人脸追踪模型(必需)

界面资源

HuiYanSDKUI.bundle

SDK 界面资源(必需)

语音播报

HuiYanAudioResource.bundle

语音播报文件(可选)

步骤 3:配置 Header Search Paths

在 Build Settings 中搜索 Header Search Paths,添加 SDK 头文件路径。

2.2 Pod 接入方式(推荐)

步骤 1:创建目录结构

在项目根目录创建文件夹结构:

代码语言:txt
复制
├── Your Project.xcodeproj
├── Podfile
├── CloudHuiYanSDK_FW/
│   ├── CloudHuiYanSDK_FW.podspec
│   ├── Frameworks/
│   │   └── HuiYanPublicSDK.framework
│   └── Resources/
│       ├── HuiYanSDKUI.bundle
│       ├── HuiYanAudioResource.bundle
│       └── face-tracker-v003.bundle
步骤 2:编写 podspec 文件

在 CloudHuiYanSDK_FW 目录下创建 CloudHuiYanSDK_FW.podspec:

代码语言:ruby
复制
Pod::Spec.new do |s|
  s.name         = "CloudHuiYanSDK_FW"
  s.version      = "1.0.0"
  s.platform     = :ios, "9.0"
  s.summary      = 'frameworks and bundle resources for youtu mobile hdr'
  s.homepage     = 'https://cloud.tencent.com/product/faceid'
  s.license      = 'MIT'
  s.source       = { :git => 'your-repo-url', :tag => "#{s.version}" }
  s.static_framework = true
  s.compiler_flags = "-ObjC"
  s.author       = { 'Tencent' => 'xxx@tencent.com' }
  s.pod_target_xcconfig = { 'VALID_ARCHS' => ['arm64', 'x86_64'] }

  s.subspec 'Resources' do |framework|
    framework.resource = 'Resources/*.bundle'
  end

  s.subspec 'Framework' do |framework|
    framework.frameworks = 'Accelerate'
    framework.vendored_frameworks = 'Frameworks/*.framework'
  end
end
步骤 3:配置 Podfile

在项目根目录的 Podfile 中添加:

代码语言:ruby
复制
target 'YourApp' do
  use_frameworks!
  pod 'CloudHuiYanSDK_FW', :path => './CloudHuiYanSDK_FW'
end
步骤 4:执行安装
代码语言:bash
复制
pod install

三、编译配置(重要!)

以下三处配置容易被忽略,缺少任何一处都会导致编译或运行错误:

3.1 Other Linker Flags 添加 -ObjC

路径:Target → Build Settings → Other Linker Flags

原因:SDK 内部包含 Objective-C 类目,缺少这个选项会报"未定义符号"错误。

配置值:添加 -ObjC

3.2 接入文件后缀改为 .mm

原因:SDK 内部使用了 C++ 语法,接入的 ViewController 需要以 Objective-C++ 方式编译。

操作:将调用 SDK 的 .m 文件后缀改为 .mm

3.3 链接 Accelerate.framework

路径:Target → Build Phases → Link Binary With Libraries

原因:部分图像处理能力依赖这个系统框架。

操作:点击 + 号,搜索并添加 Accelerate.framework

3.4 Pod 集成时的继承配置

如果使用 Pod 集成时出现 Undefined symbol: _OBJC_CLASS_$_HuiYanSDK 错误:

路径:Target → Build Settings → Other Linker Flags

配置值:添加 $(inherited)

四、权限声明

4.1 Info.plist 配置

在 Info.plist 中添加摄像头权限说明:

代码语言:xml
复制
<key>Privacy - Camera Usage Description</key>
<string>人脸核身需要开启您的摄像头权限,用于识别</string>

4.2 可选权限

SDK 不强制获取可选权限,即使没有获取可选权限,SDK 基本功能也能正常运行。你可以配置可选权限以便使用 SDK 提供的其他功能。

五、初始化与启动核身

5.1 初始化 SDK

在需要使用核身的页面中完成初始化。确保在用户同意隐私政策之后调用:

代码语言:objective-c
复制
#import <HuiYanPublicSDK/HuiYanSDKKit.h>

@interface FaceVerifyViewController ()

@end

@implementation FaceVerifyViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 确保用户已同意隐私政策后再初始化
    if ([self hasUserAgreedPrivacyPolicy]) {
        [[HuiYanSDKKit sharedInstance] initSDKWithViewController:self];
    }
}

- (BOOL)hasUserAgreedPrivacyPolicy {
    // 检查用户是否已同意隐私政策
    return YES;
}

@end

5.2 构造配置并启动核身

代码语言:objective-c
复制
#import <HuiYanPublicSDK/HuiYanSDKKit.h>
#import <HuiYanPublicSDK/AuthConfig.h>

@interface FaceVerifyViewController () <HuiYanSDKDelegate>

@property (nonatomic, copy) NSString *sdkToken;

@end

@implementation FaceVerifyViewController

// 从服务端获取 Token 后启动核身
- (void)startFaceVerifyWithToken:(NSString *)token {
    self.sdkToken = token;

    // 配置信息
    AuthConfig *config = [[AuthConfig alloc] init];
    // 设置 Token
    config.token = token;
    // 设置 License 路径(放入 Bundle 中的 license 文件)
    config.licencePath = [[NSBundle mainBundle] pathForResource:@"FaceSDK.license" ofType:@""];
    // 准备阶段超时时间(毫秒)
    config.prepareTimeoutMs = 20000;
    // 动作阶段超时时间(毫秒)
    config.actionTimeoutMs = 20000;
    // 是否删除本地活体视频缓存
    config.isDeleteVideoCache = YES;
    // 设置 UI 回调代理
    config.delegate = self;

    // 启动核身
    [[HuiYanSDKKit sharedInstance] startHuiYanAuthWithAuthConfig:config
        withProcessSucceedBlock:^(id _Nonnull resultInfo, id _Nullable retFaceidToken) {
            NSLog(@"核身成功, result: %@, faceIdToken: %@", resultInfo, retFaceidToken);
            [self handleSuccessWithToken:retFaceidToken];
        }
        withProcessFailedBlock:^(NSError * _Nonnull error, id _Nullable retFaceidToken) {
            NSLog(@"核身失败, code: %ld, msg: %@, faceIdToken: %@",
                  (long)error.code, error.userInfo[NSLocalizedDescriptionKey], retFaceidToken);
            [self handleFailureWithError:error token:retFaceidToken];
        }];
}

// 核身成功后,通知服务端拉取结果
- (void)handleSuccessWithToken:(NSString *)faceIdToken {
    // 将 faceIdToken 传给服务端,由服务端调用 GetFaceIdResult 获取最终结果
    [self verifyResultWithToken:faceIdToken];
}

// 处理核身失败
- (void)handleFailureWithError:(NSError *)error token:(NSString *)faceIdToken {
    NSString *userMessage;
    switch (error.code) {
        case -1:
            userMessage = @"网络异常,请重试";
            break;
        case -2:
            userMessage = @"摄像头未开启";
            break;
        default:
            userMessage = [NSString stringWithFormat:@"验证失败:%@", error.userInfo[NSLocalizedDescriptionKey]];
    }

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
                                                                   message:userMessage
                                                            preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alert animated:YES completion:nil];
}

// 服务端拉取结果示例
- (void)verifyResultWithToken:(NSString *)faceIdToken {
    // 请求服务端获取最终结果
    // 服务端调用 GetFaceIdResult 接口
    NSLog(@"请将 faceIdToken 传给服务端拉取结果: %@", faceIdToken);
}

#pragma mark - HuiYanSDKDelegate

- (void)onMainViewCreate:(UIView *)mainView {
    // SDK 主界面创建回调
    NSLog(@"SDK 主界面已创建");
}

- (void)onMainViewDestroy {
    // SDK 主界面销毁回调
    NSLog(@"SDK 主界面已销毁");
}

#pragma mark - 资源释放

- (void)dealloc {
    // 页面退出时释放 SDK 资源
    [HuiYanSDKKit clearInstance];
}

@end

5.3 服务端获取 Token 示例

在调用 SDK 之前,需要先通过服务端获取 SdkToken:

代码语言:python
复制
# Python 服务端示例
from tencentcloud.common import credential
from tencentcloud.faceid.v20180301 import faceid_client, models

def get_face_id_token(compare_lib="LIBRARY"):
    cred = credential.Credential("SecretId", "SecretKey")
    client = faceid_client.FaceidClient(cred, "ap-guangzhou")

    req = models.GetFaceIdTokenRequest()
    req.CompareLib = compare_lib
    resp = client.GetFaceIdToken(req)

    return resp.FaceIdToken

六、常见报错处理

报错现象

可能原因

处理方式

报 C++ 相关编译错误

接入文件未按 Objective-C++ 编译

将文件后缀 .m 改为 .mm

提示 auth path (null) 或参数错误

License 未加入 bundle 或路径配置有误

检查 config.licencePath 设置,确认 License 已添加到 Copy Bundle Resources

进入核身页面无画面

缺少 -ObjC 链接选项

在 Other Linker Flags 中添加 -ObjC

提示缺少系统框架

未链接 Accelerate.framework

在 Link Binary With Libraries 中添加

出现 Undefined symbol: _OBJC_CLASS_$_HuiYanSDK

使用 Pod 时缺少继承配置

在 Other Linker Flags 中添加 $(inherited)

摄像头权限弹窗不显示

Info.plist 未配置隐私说明

添加 Privacy - Camera Usage Description

6.1 详细排查步骤

问题:提示 auth path (null) errMsg:参数错误

  1. 检查 License 文件是否已加入 Bundle
  2. 检查 config.licencePath 是否正确指向 License 文件
  3. 确认 TARGETS -> Build Phases -> Copy Bundle Resources 中存在 License 文件

问题:使用 Pod 集成时出现未定义符号

  1. 在 TARGETS -> Build Settings -> Other Linker Flags 添加 $(inherited)
  2. 确认 podspec 中设置了 s.static_framework = true
  3. 重新执行 pod install --repo-update

七、上线前检查

  • 三处编译配置已全部完成(-ObjC、.mm 后缀、Accelerate.framework)
  • License 已加入 Bundle 且路径正确
  • 摄像头权限说明文案已配置
  • 用户拒绝隐私授权时不会调用初始化
  • SdkToken 能正常从服务端获取
  • 核身成功后能正常传回服务端
  • 页面退出时已清理 SDK 资源
  • 各种错误场景有兜底处理

腾讯云慧眼人脸核身提供 iOS 端腾讯云慧眼 SDK 接入方式,并配套集成文档与常见问题说明。该系列产品正在限时特惠活动中,低至3.3折:https://cloud.tencent.com/act/pro/happynewyears

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 摘要:
  • 一、环境要求
  • 二、两种集成方式
    • 2.1 手动接入方式
      • 步骤 1:导入 Framework
      • 步骤 2:导入资源文件
      • 步骤 3:配置 Header Search Paths
    • 2.2 Pod 接入方式(推荐)
      • 步骤 1:创建目录结构
      • 步骤 2:编写 podspec 文件
      • 步骤 3:配置 Podfile
      • 步骤 4:执行安装
  • 三、编译配置(重要!)
    • 3.1 Other Linker Flags 添加 -ObjC
    • 3.2 接入文件后缀改为 .mm
    • 3.3 链接 Accelerate.framework
    • 3.4 Pod 集成时的继承配置
  • 四、权限声明
    • 4.1 Info.plist 配置
    • 4.2 可选权限
  • 五、初始化与启动核身
    • 5.1 初始化 SDK
    • 5.2 构造配置并启动核身
    • 5.3 服务端获取 Token 示例
  • 六、常见报错处理
    • 6.1 详细排查步骤
  • 七、上线前检查
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档