├── Doc ├── logo.png ├── FaceAISDK.jpg ├── SDKWorkFlow.png ├── pod_update_FaceAISDK.jpg ├── FaceAISDK隐私协议.md ├── 历史版本SDK更新记录.md └── FaceAISDK 个人信息保护规则.md ├── FaceAISDK_iOS ├── .DS_Store ├── Assets.xcassets │ ├── Contents.json │ ├── AppIcon.appiconset │ │ ├── logo.png │ │ └── Contents.json │ ├── AccentColor.colorset │ │ └── Contents.json │ └── FaceMainColor.colorset │ │ └── Contents.json ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── FaceAISDK_iOSApp.swift ├── CustomToastView.swift ├── LivenessDetectView.swift ├── VerifyFaceView.swift ├── AddFaceByUIImage.swift ├── AddFaceByCamera.swift ├── FaceAINaviView.swift └── Localizable.xcstrings ├── FaceAISDK_iOS.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── FaceAISDK_iOS.xcscheme └── project.pbxproj ├── FaceAISDK_iOS.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── Podfile ├── .gitignore ├── LICENSE └── README.md /Doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/Doc/logo.png -------------------------------------------------------------------------------- /Doc/FaceAISDK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/Doc/FaceAISDK.jpg -------------------------------------------------------------------------------- /Doc/SDKWorkFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/Doc/SDKWorkFlow.png -------------------------------------------------------------------------------- /FaceAISDK_iOS/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/FaceAISDK_iOS/.DS_Store -------------------------------------------------------------------------------- /Doc/pod_update_FaceAISDK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/Doc/pod_update_FaceAISDK.jpg -------------------------------------------------------------------------------- /FaceAISDK_iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/Assets.xcassets/AppIcon.appiconset/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaceAISDK/FaceAISDK_iOS/HEAD/FaceAISDK_iOS/Assets.xcassets/AppIcon.appiconset/logo.png -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "logo.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/FaceAISDK_iOSApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FaceAISDK_iOSApp.swift 3 | // FaceAISDK_iOS 4 | // 5 | // Created by anylife on 2025/12/2. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct FaceAISDK_iOSApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | FaceAINaviView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '16.0' 3 | 4 | # 怎么清除缓存? 5 | # 1. pod cache clean --all 6 | # 2. pod deintegrate 7 | 8 | target 'FaceAISDK_iOS' do 9 | # Comment the next line if you don't want to use dynamic frameworks 10 | use_frameworks! 11 | 12 | 13 | # 1. 命令 pod update FaceAISDK_Core 安装更新FaceAISDK依赖,请指定版本。 14 | # 不同开发设备和网络环境,首次集成到主项目依赖同步耗时20-30分钟不等 15 | pod 'FaceAISDK_Core', '2025.12.03' 16 | 17 | 18 | 19 | end 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | *.xcodeproj/xcuserdata/ 4 | *.xcuserdatad/ 5 | DerivedData/ 6 | build/ 7 | *.xcworkspace/xcuserdata/ 8 | 9 | # Swift Package Manager (if used) 10 | .build/ 11 | Packages/ 12 | Package.pins 13 | Package.resolved 14 | 15 | # CocoaPods 16 | # We recommend against adding the Pods directory to your .gitignore. 17 | # However, if you choose to ignore it, uncomment the following line: 18 | Pods/ 19 | 20 | # If you ignore Pods/, you might also ignore this. 21 | Podfile.lock 22 | 23 | 24 | 25 | # Carthage (if used) 26 | Carthage/ 27 | 28 | # Other 29 | .swiftpm/ 30 | .idea/ 31 | .vscode/ 32 | *.swp 33 | *.bak 34 | *.orig 35 | *.pyc 36 | *.o 37 | *.d 38 | *.gcno 39 | *.gcda 40 | *.gcov 41 | *.lproj/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | FaceAISDK License 2 | 3 | 4 | 可离线人脸识别认证SDK是由FaceAISDK工作室(以下简称“我们”或“FaceAISDK”)面向应用开发者(以下简称“开发者”)提供的在应用中认证使用者是否为本人,实现人脸登录、人脸考勤等需要校验是否真实本人的能力及服务。 5 | 6 | 开发者根据FaceAISDK的开发文档和SDK源码集成指南在其应用中集成了FaceAISDK后,我们将通过被集成的FaceAISDK向开发者的最终用户(以下简称“您”或“用户”)提供相关服务,处理开发者应用相关的数据,相关数据中可能包含您的个人信息。FaceAISDK非常重视您的个人信息和隐私保护,SDK本身不用联网就能工作,设备相机访问权限仅仅从摄像头获取人脸认证图像,本SDK不收集不传输存储个人信息数据到本SDK后台。 7 | 8 | 请注意:我们要求集成FaceAISDK的所有开发者严格遵循法律法规;在接入、使用各开放能力前,我们要求开发者在其产品应用的隐私政策中向您告知其集成SDK处理个人信息的基本情况,并获取您的同意或取得其他合法性基础。但我们无法控制开发者及其开发者应用如何处理开发者所控制的个人信息,也不对其行为负责。我们建议您认真阅读开发者应用相关用户协议及隐私政策,在确认充分了解并同意开发者如何处理您的个人信息后再使用开发者应用。 9 | 10 | 11 | 版权声明:FaceAISDK的开发文档和SDK源码集成指南为了方便开发者接入可以随意下载传播。严禁复制、变更、反向工程、反汇编、反编译、拆装、企图导出本SDK源代码、解码、其他对本SDK的源代码、构造、构思等进行解析或者复制的行为; 12 | 严禁赠与、借用、租用、转让、售卖、再分发、其他再许可本软件的相关行为 13 | FaceAISDK工作室对本SDK享有和保留所有权利、其他相关权利和资格,并保留本协议未明确授予您的其他任何权利。 14 | 15 | 如何联系我们 16 | Email:FaceAISDK.Service@gmail.com -------------------------------------------------------------------------------- /FaceAISDK_iOS/Assets.xcassets/FaceMainColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "display-p3", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.275", 9 | "green" : "0.298", 10 | "red" : "0.133" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "display-p3", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.275", 27 | "green" : "0.298", 28 | "red" : "0.133" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Doc/FaceAISDK隐私协议.md: -------------------------------------------------------------------------------- 1 | ## FaceAISDK 隐私协议及个人信息保护规则 2 | 3 | 《FaceAI隐私协议及个人信息保护规则》以下简称“本规则”告知,为了实现 SDK 产品的相关功能,SDK 产品需收集、使用和处理终端用户个人信息的情况。 4 | 5 | 6 | ## 一、我们收集的信息及我们如何使用信息 7 | SDK授权以及正常运行都是离线不需要联网,所有信息都是本地处理,缓存在宿主App私有目录,仅需卸载本Demo App所有信息即时清除。 8 | 但为实现SDK的相应功能所必须,我们将向终端用户收集在使用与SDK产品相关的功能时产生的如下个人信息: 9 | 10 | | 个人信息类型 | 处理目的 | 处理方式 | 11 | |:-------|:------------------------------:|:---------------:| 12 | | 设备型号 | 根据设备的型号判断设备硬件配置高低,以便动态调整引擎参数 | 仅本地运行判断,不收集上报 | 13 | | 操作系统版本 | 需要据此判断设备系统版本,做兼容处理,不采集可能导致使用异常 | 本地化处理,不收集上报 | 14 | | 人脸特征值 | 用于人脸识别 活体检测和注册采集人脸数据,分析出人脸特征数据 | SDK本地化处理,人脸特征信息 | 15 | 16 | 17 | ## (二) 为实现 SDK 产品功能所需的权限 18 | 为实现 SDK 产品的相应功能所必须,我们会通过开发者的应用申请所需权限。 19 | 20 | | 操作系统 | 权限名称 | 使用目的 | 21 | |:------------|:----:|:----------------------------------:| 22 | | Android&iOS | 相机 | 获取视频帧进行人脸识别和人脸注册获取特征值,不授权则无法使用相应功能 | 23 | 24 | 当终端用户关闭权限即代表其取消了相应的授权,我们和开发者将不会继续收集和使用相关权限所对应的个人信息,也无法为终端用户提供需要终端用户开启权限才能提供的对应的功能。 25 | 26 | ## 如何联系我们 27 | 28 | 在集成SDK 前如有疑问,请联系 FaceAISDK.Service@gmail.com 29 | -------------------------------------------------------------------------------- /Doc/历史版本SDK更新记录.md: -------------------------------------------------------------------------------- 1 | 如果运行出现以下错误 2 | ``` 3 | Swift/Integers.swift:3564: Fatal error: Not enough bits to represent the passed value 4 | ``` 5 | 请在Xcode菜单Product执行clean all Issues后 再次执行pod命令升级FaceAISDK就可以了。 6 | ``` 7 | pod update FaceAISDK_Core 8 | ``` 9 | 10 | ## V2025.12.03 11 | - 解决运行时tensorflow Interpreter delegates 无法访问问题 12 | 13 | ## V2025.12.01 14 | - 提示iOS 版本识别精度 15 | - 支持Xcode15.2+ 16 | - 人脸特征值处理优化 17 | 18 | 19 | ## V2025.11.29 20 | - 统一Android&iOS 的人脸特征值长度为1024 21 | - 识别精确度优化阶段1 22 | - 其它API 精简优化 23 | 24 | 25 | ## V2025.11.15 26 | - 人脸录入裁剪方式修改,**老的人脸需要重新矫正一次数据或重新录入人脸** 27 | - SDK 内部流程优化 28 | - 支持通过相册UIImage添加人脸 29 | 30 | 31 | ## V2025.10.28 32 | - SDK闪退问题处理 33 | - 动作活体随机组合优化 34 | 35 | 36 | ## V2025.10.21 37 | - 动作活体支持 1.张张嘴 2.微笑 3.眨眨眼 4.摇头 5.点头 自由组合 38 | - SwiftUI 更新,UI卡顿优化 39 | - 所有返回添加状态码,以便根据状态码多语言国际化 40 | 41 | 42 | ## V2025.09.30 43 | - 降级Swift版本到6.0 ,默认Xcode 版本16.2 44 | - 更新ReadME 说明和注释 45 | - 处理 Not enough bits to represent the passed value 问题 46 | 47 | 48 | ## V2025.09.11 49 | - 使用Swift + SwiftUI 重构SDK Demo 50 | 51 | ## V2025.05.31 52 | - 废弃Object C SDK 接入Demo示范,规划Swift实现 53 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/CustomToastView.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import SwiftUI 3 | 4 | // 5 | // CustomToastView.swift 6 | // SDKDebug 7 | // 8 | // Created by anylife on 2025/12/2. 9 | 10 | 11 | // 自定义ToastView 提示 12 | struct CustomToastView: View { 13 | let message: String 14 | let style: ToastStyle 15 | // ... CustomToastView 的实现如上所示 ... 16 | var body: some View { 17 | VStack { 18 | HStack { 19 | Text(message) 20 | .foregroundColor(.white) 21 | .font(.system(size: 19).bold()) 22 | .padding(.vertical, 14) 23 | .padding(.horizontal, 22) 24 | } 25 | .background(style.backgroundColor) 26 | .cornerRadius(25) 27 | .shadow(radius: 5) 28 | } 29 | } 30 | } 31 | 32 | // 定义 Toast 样式 33 | enum ToastStyle { 34 | case success 35 | case failure 36 | var backgroundColor: Color { 37 | switch self { 38 | case .success: return Color.faceMain 39 | case .failure: return Color.red 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 27 | 28 | 29 | 31 | 32 | 34 | 35 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Doc/FaceAISDK 个人信息保护规则.md: -------------------------------------------------------------------------------- 1 | ## FaceAISDK 开发者使用提示及个人信息保护规则 2 | 3 | 《FaceAI离线人脸识别SDK 个人信息保护规则》(以下简称“本规则”)主要向开发者及其终端用户(“终端用户”)告知,为了实现 SDK 产品的相关功能,SDK 产品需收集、使用和处理终端用户个人信息的情况。 4 | 5 | ## 特别说明 6 | SDK接入方应遵守当地法律、法规收集、使用和处理终端用户的个人信息,包括但不限于制定和公布有关个人信息保护的隐私政策等。 7 | 8 | 在集成 SDK 产品前,告知终端用户 SDK 产品收集、使用和处理终端用户个人信息的情况,并依法征得终端用户同意。 9 | 在征得终端用户的同意前,除非法律法规另有规定,不应收集任何终端用户的个人信息。 10 | 11 | 向终端用户提供易于操作且满足法律法规要求的用户权利实现机制,并告知终端用户如何查阅、复制、修改、删除个人信息,撤回同意,以及限制个人信息处理、转移个人信息、获取个人信息副本和注销账号。 12 | 13 | 更多请参考 https://www.cac.gov.cn/2025-03/21/c_1744174262156096.htm 14 | 请开发者根据本规则说明以合适的方式在宿主App中告知并取得用户的统一后才提供本SDK 服务 15 | 16 | ## 一、我们收集的信息及我们如何使用信息 17 | SDK授权以及正常运行都是离线不需要联网,所有信息都是本地处理,缓存在宿主App私有目录。 18 | 但为实现SDK的相应功能所必须,我们将向终端用户或开发者收集终端用户在使用与SDK产品相关的功能时产生的如下个人信息: 19 | 20 | | 个人信息类型 | 处理目的 | 处理方式 | 21 | |:-------|:------------------------------:|:---------------:| 22 | | 设备型号 | 根据设备的型号判断设备硬件配置高低,以便动态调整引擎参数 | 仅本地运行判断,不收集上报 | 23 | | 操作系统版本 | 需要据此判断设备系统版本,做兼容处理,不采集可能导致使用异常 | 本地化处理,不收集上报 | 24 | | 人脸特征值 | 用于人脸识别 活体检测和注册采集人脸数据,分析出人脸特征数据 | SDK本地化处理,人脸特征信息 | 25 | 26 | 27 | ## (二) 为实现 SDK 产品功能所需的权限 28 | 为实现 SDK 产品的相应功能所必须,我们会通过开发者的应用申请所需权限。 29 | 30 | | 操作系统 | 权限名称 | 使用目的 | 31 | |:------------|:----:|:----------------------------------:| 32 | | Android&iOS | 相机 | 获取视频帧进行人脸识别和人脸注册获取特征值,不授权则无法使用相应功能 | 33 | 34 | 当终端用户关闭权限即代表其取消了相应的授权,我们和开发者将不会继续收集和使用相关权限所对应的个人信息,也无法为终端用户提供需要终端用户开启权限才能提供的对应的功能。 35 | 36 | ## 如何联系我们 37 | 38 | 在集成SDK 前如有疑问,请联系 FaceAISDK.Service@gmail.com 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | ## FaceAISDK 介绍 10 | iPhone&iPad iOS FaceAISDK is on_device Offline Face Detection 、Recognition 、Liveness Detection Anti Spoofing SDK. 11 | FaceAISDK_iOS SDK是设备端可完全离线不需联网实现人脸录入、动作活体检测、人脸识别,集成后可快速实现相关功能。 12 | 13 | 14 | ![FaceAISDK](/Doc/SDKWorkFlow.png) 15 | 16 | 17 | ## 更新说明 V2025.12.03 18 | - 提示iOS 版本识别精度和性能 19 | - 支持Xcode15.2+ ,Swift 5.9 20 | - 人脸特征值处理优化,统一长度为1024 21 | 22 | 23 | [更多历史版本介绍见](/Doc/历史版本SDK更新记录.md) 24 | 25 | ## 集成步骤 26 | 27 | SDK默认的开发环境为Xcode 15.2 ,Swift 5.9;UI全部使用SwiftUI实现,支持iOS[16,26] 28 | 29 | **集成运行本SDK 示范工程,你的电脑需要能科学上网翻墙同步依赖,因为部分资源托管在GitHub,否则无法编译成功** 30 | 31 | 32 | ### 1. 确认电脑能科学上网翻墙后,使用Pod命令安装FaceAISDK和相关依赖库 33 | 一般pod install 命令能完整的下载同步安装好所有依赖,也可以pod update FaceAISDK_Core仅更新人脸识别SDK 34 | 不同开发设备和网络环境,**首次**集成到主项目翻墙安装依赖**耗时25分钟左右**,建议此时去喝杯水活动一下颈椎😭 35 | 36 | **Install TensorFlowLiteSwift (2.17.0) 这是最耗时的基础依赖安装** 37 | 你也可以在浏览器中看看当前网络环境下载TensorFlowLiteSwift情况: 38 | https://github.com/tensorflow/tensorflow/archive/refs/heads/master.zip 39 | 40 | ``` 41 | 「没有翻墙的错误提示」 42 | Updating local specs repositories 43 | Downloading dependencies 44 | Installing FaceAISDK_Core 2025.10.17 45 | 46 | [!] Error installing FaceAISDK_Core 47 | [!] /usr/bin/git clone https://github.com/FaceAISDK/FaceAISDK_Core.git /var/folders/gh/p4wv4ytj4tn5xrhgq0n_jnbm0000gn/T/d20251020-8626-c57agm --template= --single-branch --depth 1 --branch 2025.10.17 48 | 49 | Cloning into '/var/folders/gh/p4wv4ytj4tn5xrhgq0n_jnbm0000gn/T/d20251020-8626-c57agm'... 50 | fatal: unable to access 'https://github.com/FaceAISDK/FaceAISDK_Core.git/': Error in the HTTP2 framing layer 51 | ``` 52 | **经过漫长的等待,编译完成后 就可以在体验效果了** 53 | 54 | 55 | ### 2. 编译FaceAISDK相关问题 56 | 如果调试运行出现以下错误 57 | 58 | ``` 59 | Swift/Integers.swift:3564: Fatal error: Not enough bits to represent the passed value 60 | 或 61 | tensorflow Interpreter delegates 无法访问问题 62 | ``` 63 | 64 | 请在Xcode菜单Product执行clean all Issues后 再次执行以下pod命令更新FaceAISDK就可以了。 65 | 66 | ``` 67 | pod update FaceAISDK_Core 68 | ``` 69 | 70 | ## 其他说明 71 | 72 | 微信:FaceAISDK 73 | Email: FaceAISDK.Service@gmail.com 74 | iOS SDK: https://github.com/FaceAISDK/FaceAISDK_iOS 75 | Android: https://github.com/FaceAISDK/FaceAISDK_Android 76 | 77 | 78 | ![FaceAISDK](/Doc/FaceAISDK.jpg) 79 | 80 | ## Android体验Demo APK下载如下 81 | 82 |
83 | 84 |
85 | 86 | . 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcodeproj/xcshareddata/xcschemes/FaceAISDK_iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 42 | 44 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 66 | 68 | 74 | 75 | 76 | 77 | 79 | 80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/LivenessDetectView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import AVFoundation 3 | import FaceAISDK_Core 4 | 5 | 6 | /** 7 | * 动作活体检测,(iOS 目前仅支持动作活体,静默 炫彩等排期) 8 | * UI 样式仅供参考,根据你的业务可自行调整 9 | */ 10 | struct LivenessDetectView: View { 11 | //确保ViewModel的生命周期与视图一致,使用@StateObject持有ViewModel,视图被销毁时会一起释放 12 | @StateObject private var viewModel: VerifyFaceModel = VerifyFaceModel() 13 | @State private var showToast = false 14 | @Environment(\.dismiss) private var dismiss 15 | 16 | //录入保存的FaceID 值。一般是你的业务体系中个人的唯一编码,比如账号 身份证 17 | let faceID: String 18 | 19 | let onDismiss: (FaceVerifyResult) -> Void 20 | 21 | 22 | //根据提示状态码多语言展示文本 23 | //添加人脸状态码参考 AddFaceTipsCode 24 | private func localizedTip(for code: Int) -> String { 25 | let key = "Face_Tips_Code_\(code)" 26 | let defaultValue = "LivenessDetect Tips Code=\(code)" 27 | return NSLocalizedString(key, value: defaultValue, comment: "") 28 | } 29 | 30 | 31 | var body: some View { 32 | VStack { 33 | Text(localizedTip(for: viewModel.sdkInterfaceTips.code)) 34 | .font(.system(size: 20).bold()) 35 | .padding(.horizontal,20) 36 | .padding(.vertical,8) 37 | .foregroundColor(.white) 38 | .background(Color.faceMain) 39 | .cornerRadius(20) 40 | 41 | Text(localizedTip(for: viewModel.sdkInterfaceTipsExtra.code)) 42 | .font(.system(size: 19).bold()) 43 | .padding(.bottom, 6) 44 | .frame(minHeight: 30) 45 | .foregroundColor(.black) 46 | 47 | FaceAICameraView(session: viewModel.captureSession,cameraSize: FaceCameraSize) 48 | .frame( 49 | width: FaceCameraSize, 50 | height: FaceCameraSize) 51 | .aspectRatio(1.0, contentMode: .fit) //Enforce1:1ratio 52 | .clipShape(Circle()) //Clip to ensure square bounds 53 | 54 | Spacer() 55 | } 56 | 57 | .onAppear { 58 | //初始化人脸引擎 59 | //是否仅仅需要动作活体检测,动作活体目前是随机的两个步骤 60 | // motionLiveness 指定活体动作的种类(至少3种) 1.张张嘴 2.微笑 3.眨眨眼 4.摇摇头 5.点头 61 | viewModel.initFaceAISDK(faceIDFeature: "",onlyLiveness: true,motionLiveness:[1,2,3,4,5]) 62 | } 63 | 64 | .onChange(of: viewModel.faceVerifyResult.code) { newValue in 65 | showToast = true 66 | print("动作活体检测返回 : \(viewModel.faceVerifyResult)") 67 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { 68 | showToast = false 69 | onDismiss(viewModel.faceVerifyResult) // 传值给父视图 70 | dismiss() // 关闭页面 71 | } 72 | } 73 | 74 | .onDisappear{ 75 | viewModel.stopFaceVerify() //停止 76 | } 77 | .padding() 78 | .frame(maxWidth: .infinity, maxHeight: .infinity) // 确保填满可用空间 79 | .background(Color.white.ignoresSafeArea()) // 扩展到安全区域 80 | 81 | if showToast { 82 | VStack { 83 | Spacer() 84 | CustomToastView( 85 | message: "\(viewModel.faceVerifyResult.tips)", 86 | style: ToastStyle.success 87 | ) 88 | .padding(.bottom, 60) // 放置在底部 89 | } 90 | .transition(.move(edge: .bottom).combined(with: .opacity)) // 添加过渡动画 91 | .animation(.easeInOut(duration: 0.3), value: showToast) // 动画控制 92 | } 93 | 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/VerifyFaceView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import AVFoundation 3 | import FaceAISDK_Core 4 | 5 | 6 | /** 7 | * 人脸识别,摄像头采集画面需要真机调试 8 | * UI 样式仅供参考,根据你的业务可自行调整 9 | */ 10 | struct VerifyFaceView: View { 11 | //确保ViewModel的生命周期与视图一致,使用@StateObject持有ViewModel,视图被销毁时会一起释放 12 | @StateObject private var viewModel: VerifyFaceModel = VerifyFaceModel() 13 | @Environment(\.dismiss) private var dismiss 14 | 15 | @State private var showToast = false 16 | @State private var toastViewTips: String = "" 17 | 18 | //录入保存的FaceID 值。一般是你的业务体系中个人的唯一编码,比如账号 身份证 19 | let faceID: String 20 | //人脸相似度阈值,范围0.8到0.9. 21 | //设置的相似度阈值越高,对人脸角度,环境光线和摄像头宽动态要求越高 22 | let threshold:Float 23 | let onDismiss: (Int) -> Void 24 | 25 | 26 | //根据提示状态码多语言展示文本 27 | //添加人脸状态码参考 AddFaceTipsCode 28 | private func localizedTip(for code: Int) -> String { 29 | let key = "Face_Tips_Code_\(code)" 30 | let defaultValue = "VerifyFace Tips Code=\(code)" 31 | return NSLocalizedString(key, value: defaultValue, comment: "") 32 | } 33 | 34 | var body: some View { 35 | VStack { 36 | Text(localizedTip(for: viewModel.sdkInterfaceTips.code)) 37 | .font(.system(size: 20).bold()) 38 | .padding(.horizontal,20) 39 | .padding(.vertical,8) 40 | .foregroundColor(.white) 41 | .background(Color.faceMain) 42 | .cornerRadius(20) 43 | 44 | Text(localizedTip(for: viewModel.sdkInterfaceTipsExtra.code)) 45 | .font(.system(size: 19).bold()) 46 | .padding(.bottom, 6) 47 | .frame(minHeight: 30) 48 | .foregroundColor(.black) 49 | 50 | FaceAICameraView(session: viewModel.captureSession,cameraSize: FaceCameraSize) 51 | .frame( 52 | width: FaceCameraSize, 53 | height: FaceCameraSize) 54 | .aspectRatio(1.0, contentMode: .fit) //Enforce1:1ratio 55 | .clipShape(Circle()) //Clip to ensure square bounds 56 | .overlay(Circle().stroke(Color.gray, lineWidth: 1)) 57 | 58 | Spacer() 59 | } 60 | 61 | .onAppear { 62 | //初始化人脸引擎,设置人脸识别的底片和比对相似度阈值(0.8到0.95) 63 | //设置的相似度阈值越高,对人脸角度,环境光线和摄像头宽动态要求越高 64 | // motionLiveness 指定活体动作的种类(至少3种) 1.张张嘴 2.微笑 3.眨眨眼 4.摇摇头 5.点头 65 | 66 | //人脸特征值是一个1024长度的字符串,已经和Android 同步实现了数据互联互通 67 | guard let faceFeature = UserDefaults.standard.string(forKey: faceID) else { 68 | 69 | toastViewTips="No Face Feature for key" 70 | showToast = true 71 | 72 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { 73 | showToast = false 74 | onDismiss(VerifyResultCode.NO_FACE_FEATURE) //传值给父视图 75 | dismiss() //关闭页面 76 | } 77 | 78 | return 79 | } 80 | 81 | //motionLiveness 改为和Android 同步类型 82 | viewModel.initFaceAISDK(faceIDFeature: faceFeature, threshold: threshold, onlyLiveness: false,motionLiveness:[1,3,4,5]) 83 | } 84 | 85 | .onChange(of: viewModel.faceVerifyResult.code) { newValue in 86 | toastViewTips=viewModel.faceVerifyResult.tips 87 | print("ViewModel 返回 : \(viewModel.faceVerifyResult)") 88 | showToast = true 89 | 90 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { 91 | showToast = false 92 | onDismiss(viewModel.faceVerifyResult.code) //传值给父视图 93 | dismiss() //关闭页面 94 | } 95 | } 96 | 97 | .onDisappear{ 98 | viewModel.stopFaceVerify() //停止 99 | } 100 | .padding() 101 | .frame(maxWidth: .infinity, maxHeight: .infinity) // 确保填满可用空间 102 | .background(Color.white.ignoresSafeArea()) // 扩展到安全区域 103 | 104 | if showToast { 105 | // 根据结果和阈值计算样式和文本 106 | let similarity = String(format: "%.2f", viewModel.faceVerifyResult.similarity) 107 | let currentTips = viewModel.faceVerifyResult.tips // 直接使用 ViewModel 的最新值 108 | 109 | let toastStyle: ToastStyle = (viewModel.faceVerifyResult.similarity > threshold) ? .success : .failure 110 | 111 | VStack { 112 | Spacer() 113 | 114 | CustomToastView( 115 | message: "\(currentTips) \(similarity)", 116 | style: toastStyle 117 | ) 118 | .padding(.bottom, 60) // 放置在底部 119 | } 120 | .transition(.move(edge: .bottom).combined(with: .opacity)) // 添加过渡动画 121 | .animation(.easeInOut(duration: 0.3), value: showToast) // 动画控制 122 | } 123 | 124 | 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/AddFaceByUIImage.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import PhotosUI //PhotosUI 框架 3 | import FaceAISDK_Core 4 | 5 | 6 | public struct AddFaceByUIImage: View { 7 | 8 | @State private var selectedItem: PhotosPickerItem? 9 | @State private var isLoading = false 10 | @State private var canSave = false 11 | 12 | 13 | // 用于存储最终加载并用于显示的 SwiftUI Image ,会自动销毁吗? 14 | @State private var selectedImage: UIImage? 15 | 16 | @StateObject private var viewModel: addFaceByUIImageModel = addFaceByUIImageModel() 17 | 18 | //录入保存的FaceID 值。一般是你的业务体系中个人的唯一编码,比如账号 身份证 19 | let faceID: String 20 | let onDismiss: (String?) -> Void 21 | 22 | 23 | //根据提示状态码多语言展示文本 24 | //添加人脸状态码参考 AddFaceTipsCode 25 | private func localizedTip(for code: Int) -> String { 26 | let key = "Face_Tips_Code_\(code)" 27 | let defaultValue = "LivenessDetect Tips Code=\(code)" 28 | return NSLocalizedString(key, value: defaultValue, comment: "") 29 | } 30 | 31 | 32 | public var body: some View { 33 | VStack(spacing: 2) { 34 | 35 | Text(localizedTip(for: viewModel.sdkInterfaceTips.code)) 36 | .font(.system(size: 18).bold()) 37 | .padding(.vertical,22) 38 | .foregroundColor(.white) 39 | .cornerRadius(20) 40 | 41 | 42 | // 用于显示选择的图片 43 | if let selectedImage { 44 | ZStack { 45 | Image(uiImage: selectedImage) 46 | .resizable() 47 | .scaledToFit() 48 | .frame(maxWidth: 200, maxHeight: 200) 49 | .clipShape(RoundedRectangle(cornerRadius: 12)) 50 | .shadow(radius: 5) 51 | 52 | if isLoading { 53 | ProgressView() 54 | .scaleEffect(2.0) 55 | .padding() 56 | .background(Color.black.opacity(0.7)) 57 | .cornerRadius(7) 58 | } 59 | } 60 | } else { 61 | // 默认占位符视图 62 | Image(systemName: "photo.fill") 63 | .resizable() 64 | .scaledToFit() 65 | .frame(width: 200, height: 200) 66 | .foregroundStyle(.tertiary) 67 | Text("请从相册中选择一张图片") 68 | .font(.subheadline) 69 | .foregroundStyle(.secondary) 70 | } 71 | 72 | // 3. PhotosPicker 视图 73 | PhotosPicker( 74 | selection: $selectedItem, // 绑定到 PhotosPickerItem 75 | matching: .images, // 只允许选择图片 76 | label: { 77 | Label("选择图片", systemImage: "photo.on.rectangle.angled") 78 | .frame(maxWidth: 300, maxHeight: 30) 79 | .font(.headline) 80 | } 81 | ) 82 | .padding(.top,33) 83 | .buttonStyle(.borderedProminent) 84 | .tint(.blue) 85 | 86 | if canSave { 87 | Button("保存人脸数据"){ 88 | //保存人脸特征值。人脸图如果业务有需要也可以保存,SDK不需要人脸图只需要人脸特征 89 | //人脸特征值长度 1024 90 | var faceFeature=viewModel.getFaceFeature(faceUIImage: selectedImage!); 91 | UserDefaults.standard.set(faceFeature, forKey: faceID) 92 | print("UIImage 特征值 \(faceFeature)") 93 | 94 | viewModel.confirmSaveFace(fileName: faceID) 95 | onDismiss("保存成功") 96 | } 97 | .padding(.top,22) 98 | .frame(maxWidth: .infinity) 99 | .font(.headline) 100 | .tint(.green) 101 | .buttonStyle(.borderedProminent) 102 | } 103 | 104 | 105 | } 106 | .padding() 107 | .onChange(of: selectedItem) { newValue in 108 | // 当用户选择了新的图片时,执行加载任务 109 | Task { 110 | // 将 PhotosPickerItem 加载为 Data 111 | // 我们使用 loadTransferable 来获取 Data 类型 112 | if let data = try? await newValue?.loadTransferable(type: Data.self) { 113 | // 将 Data 转换为 UIImage 114 | if let uiImage = UIImage(data: data) { 115 | isLoading = true 116 | canSave = false 117 | // 将 UIImage 转换为 SwiftUI 的 Image 并更新状态 118 | selectedImage=uiImage 119 | //Alpha 版本,通过传入UIImage添加人脸 120 | viewModel.addFaceByUIImage(faceUIImage: uiImage) 121 | } 122 | } 123 | } 124 | } 125 | .onChange(of: viewModel.croppedFaceImage) { newValue in 126 | selectedImage=newValue 127 | isLoading = false 128 | canSave = true 129 | } 130 | 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/AddFaceByCamera.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import AVFoundation 3 | import FaceAISDK_Core 4 | 5 | // 使用 @MainActor 确保在主线程访问 6 | @MainActor 7 | var FaceCameraSize: CGFloat { 8 | 4 * min(UIScreen.main.bounds.width, UIScreen.main.bounds.height) / 5 9 | } 10 | 11 | public struct AddFaceByCamera: View { 12 | let faceID: String 13 | let onDismiss: (String?) -> Void //返回人脸特征值字符串,长度1024. 14 | 15 | @StateObject private var viewModel: AddFaceByCameraModel = AddFaceByCameraModel() 16 | 17 | // 辅助函数:获取本地化提示 18 | private func localizedTip(for code: Int) -> String { 19 | let key = "Face_Tips_Code_\(code)" 20 | let defaultValue = "Add Face Tips Code=\(code)" 21 | return NSLocalizedString(key, value: defaultValue, comment: "") 22 | } 23 | 24 | public var body: some View { 25 | VStack(spacing: 22) { 26 | // 1. 顶部提示区域 27 | Text(localizedTip(for: viewModel.sdkInterfaceTips.code)) 28 | .font(.system(size: 20).bold()) 29 | .padding(.horizontal, 20) 30 | .padding(.vertical, 8) 31 | .foregroundColor(.white) 32 | .background(Color.faceMain) // 假设 Color.faceMain 已定义 33 | .cornerRadius(20) 34 | 35 | // 2. 核心区域:相机与确认弹窗的容器 36 | // 使用 ZStack 让两者重叠在同一区域 37 | ZStack { 38 | // 图层 A: 相机预览 (底层) 39 | FaceAICameraView(session: viewModel.captureSession, cameraSize: FaceCameraSize) 40 | .aspectRatio(1.0, contentMode: .fit) 41 | .clipShape(Circle()) // 裁剪为圆形 42 | .background(Circle().fill(Color.white)) // 相机背景 43 | .overlay(Circle().stroke(Color.gray, lineWidth: 1)) 44 | 45 | // 图层 B: 确认对话框 (顶层) 46 | if viewModel.readyConfirmFace { 47 | 48 | // B2. 对话框实体 49 | ConfirmAddFaceDialog( 50 | viewModel: viewModel, 51 | cameraSize: FaceCameraSize, // 传入尺寸以适配 52 | onConfirm: { 53 | //保存人脸特征值,选择符合业务需求的保存方式 54 | UserDefaults.standard.set(viewModel.faceFeatureBySDKCamera, forKey: faceID) 55 | print("FaceFeature: \(viewModel.faceFeatureBySDKCamera!)") 56 | 57 | //人脸图如果业务有需要也可以保存,SDK不需要人脸图只需要人脸特征 58 | let savedPath = viewModel.confirmSaveFace(fileName: faceID) 59 | 60 | onDismiss(viewModel.faceFeatureBySDKCamera) 61 | } 62 | ) 63 | 64 | } 65 | } 66 | .frame(width: FaceCameraSize, height: FaceCameraSize) // 强制容器尺寸一致 67 | 68 | Spacer() 69 | } 70 | .padding() 71 | .frame(maxWidth: .infinity, maxHeight: .infinity) 72 | .background(Color.white.ignoresSafeArea()) 73 | .onAppear { 74 | viewModel.initAddFace() 75 | } 76 | .onChange(of: viewModel.sdkInterfaceTips.code) { newValue in 77 | print("🔔 AddFaceBySDKCamera: \(viewModel.sdkInterfaceTips.message)") 78 | } 79 | .onDisappear { 80 | viewModel.stopAddFace() 81 | } 82 | } 83 | 84 | 85 | // MARK: - 确认对话框组件 86 | struct ConfirmAddFaceDialog: View { 87 | // 使用 @ObservedObject 监听 viewModel 变化,或者直接传入 let 引用(如果父视图刷新机制已覆盖) 88 | // 这里沿用你原来的 let 定义,因为父视图 AddFaceByCamera 已经持有 @StateObject 89 | let viewModel: AddFaceByCameraModel 90 | let cameraSize: CGFloat 91 | let onConfirm: () -> Void 92 | 93 | var body: some View { 94 | VStack(alignment: .center, spacing: 11) { 95 | 96 | Text("Confirm Add Face Title") 97 | .font(.system(size: 19).bold()) 98 | .foregroundColor(.faceMain) // 确保你有定义这个颜色,否则用 .blue 99 | .padding(.top, 12) 100 | 101 | Image(uiImage: viewModel.croppedFaceImage) 102 | .resizable() 103 | .scaledToFill() 104 | .frame(width: 132, height: 132) // 保持你原来的大小或微调 105 | // .clipShape(Circle()) // 圆形裁剪 106 | .cornerRadius(8) 107 | .shadow(radius: 2) 108 | 109 | 110 | Text("Confirm Add Face Tips") 111 | .multilineTextAlignment(.center) 112 | .foregroundColor(.gray) // 稍微浅一点的颜色 113 | .font(.system(size: 16).bold()) 114 | .padding(.horizontal) 115 | .padding(.vertical, 3) 116 | 117 | HStack(spacing: 16) { 118 | Button(action: { 119 | viewModel.reInit() 120 | }) { 121 | Text("Retry") 122 | .frame(maxWidth: .infinity, maxHeight: 44) 123 | .background(Color.gray.opacity(0.2)) 124 | .foregroundColor(.black) 125 | .cornerRadius(7) 126 | } 127 | 128 | Button(action: { 129 | onConfirm() 130 | }) { 131 | Text("Confirm") 132 | .frame(maxWidth: .infinity, maxHeight: 44) 133 | .background(Color.blue) 134 | .foregroundColor(.white) 135 | .cornerRadius(7) 136 | } 137 | } 138 | .padding() 139 | } 140 | // 确保对话框在相机区域内居中 141 | .frame(width: cameraSize+12, height: cameraSize+12) 142 | .background(Color.white) // 背景透明,依靠外层的 ZStack Circle 遮挡 143 | .cornerRadius(9) 144 | .shadow(radius: 8) 145 | } 146 | } 147 | 148 | 149 | } 150 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/FaceAINaviView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import FaceAISDK_Core 3 | 4 | /** 5 | * iOS FaceAISDK 功能导航页面 6 | */ 7 | struct FaceAINaviView: View { 8 | 9 | @State private var navigationPath = NavigationPath() 10 | @State private var addFaceResult: String? 11 | 12 | //录入保存的FaceID 值。一般是你的业务体系中个人的唯一编码,比如账号 身份证 13 | private let faceID="yourFaceID"; 14 | 15 | var body: some View { 16 | NavigationStack(path: $navigationPath) { 17 | ZStack { 18 | Color.faceMain.ignoresSafeArea() 19 | VStack(spacing: 20) { 20 | 21 | //通过SDK相机录入人脸 22 | Button("Add Face By Camera") { 23 | navigationPath.append(FaceAINaviDestination.AddFacePageView(faceID)) 24 | } 25 | .font(.system(size: 20).bold()) 26 | .controlSize(.large) 27 | .foregroundColor(Color.white) 28 | .padding(.top,30) 29 | 30 | //通过相册录入人脸 31 | Button("Add Face From Album") { 32 | navigationPath.append(FaceAINaviDestination.AddFaceFromAlbum(faceID)) 33 | } 34 | .font(.system(size: 19).bold()) 35 | .controlSize(.large) 36 | .foregroundColor(Color.white) 37 | .padding(.top,15) 38 | 39 | //人脸识别+活体检测 40 | Button("Face Verify and Liveness Detection") { 41 | navigationPath.append(FaceAINaviDestination.VerifyFacePageView(faceID)) 42 | } 43 | .font(.system(size: 20).bold()) 44 | .foregroundColor(Color.white) 45 | .padding(.top,22) 46 | 47 | //仅动作活体检测 48 | Button("ONLY Motion Liveness Detection") { 49 | navigationPath.append(FaceAINaviDestination.LivenessView(faceID)) 50 | } 51 | .font(.system(size: 20).bold()) 52 | .foregroundColor(Color.white) 53 | .padding(.top,20) 54 | 55 | //判断faceID对应人脸特征值是否存在 56 | Button("is Face Feature Exist") { 57 | //人脸特征值是一个1024长度的字符串,已经和Android 同步实现了数据互联互通 58 | guard let faceFeature = UserDefaults.standard.string(forKey: faceID) else { 59 | print("isFaceFeatureExist? : No ! ") 60 | return 61 | } 62 | 63 | print("\n😊FaceFeature: \(faceFeature)") 64 | } 65 | 66 | .font(.system(size: 18).bold()) 67 | .foregroundColor(Color.white) 68 | .padding(.top,33) 69 | 70 | 71 | Spacer() 72 | 73 | Button("About us"){ 74 | // 记得切换成iOS 的介绍版本 75 | let url = URL(string: "https://mp.weixin.qq.com/s/R43s70guLqxA6JPEdWtjcA") 76 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 77 | if UIApplication.shared.canOpenURL(url!) { 78 | UIApplication.shared.open(url!) 79 | } 80 | } 81 | } 82 | .padding(.bottom,11) 83 | .foregroundColor(Color.white) 84 | .font(.system(size: 16).bold()) 85 | } 86 | } 87 | .navigationTitle("🧭 FaceAISDK") 88 | .navigationDestination(for: FaceAINaviDestination.self) { destination in 89 | switch destination { 90 | 91 | case .AddFacePageView(let param): 92 | AddFaceByCamera(faceID: param,onDismiss: { result in 93 | addFaceResult = result 94 | if !navigationPath.isEmpty { // 检查路径是否为空 95 | navigationPath.removeLast() 96 | } 97 | }) 98 | 99 | case .AddFaceFromAlbum(let param): 100 | 101 | AddFaceByUIImage(faceID: param,onDismiss: { result in 102 | addFaceResult = result 103 | if !navigationPath.isEmpty { // 检查路径是否为空 104 | navigationPath.removeLast() 105 | } 106 | }) 107 | 108 | case .VerifyFacePageView(let param): 109 | //设置的相似度阈值threshold越高,对人脸角度,环境光线和摄像头宽动态要求越高 110 | VerifyFaceView(faceID: param,threshold: 0.83, onDismiss: { resultCode in 111 | 112 | // resultCode, 参考 VerifyResultCode 113 | // -2 人脸识别动作活体检测超过10秒 114 | // -1 多次切换人脸或检查失败 115 | // 0 默认值 116 | // 1 人脸识别对比成功大于设置的threshold 117 | // 2 人脸识别对比识别小于设置的threshold 118 | print("VerifyResultCode :\(resultCode)") 119 | 120 | if !navigationPath.isEmpty { // 检查路径是否为空 121 | navigationPath.removeLast() 122 | } 123 | }) 124 | case .LivenessView(let param): 125 | 126 | // faceVerifyResult.code 127 | // -2 人脸识别动作活体检测超过10秒 128 | // -1 多次切换人脸或检查失败 129 | // 0 默认值 130 | // 3 动作活体检测成功 131 | LivenessDetectView(faceID: param,onDismiss: { result in 132 | print("Motion Liveness Result:\(result.tips) \(result.code)") 133 | if !navigationPath.isEmpty { // 检查路径是否为空 134 | navigationPath.removeLast() 135 | } 136 | }) 137 | 138 | } 139 | } 140 | } 141 | .onAppear { 142 | //和合适的场景,提前一点初始化FaceAISDK 143 | FaceAISDK.initSDK() 144 | } 145 | } 146 | 147 | } 148 | 149 | enum FaceAINaviDestination: Hashable { 150 | case AddFaceFromAlbum(String) 151 | case AddFacePageView(String) 152 | case VerifyFacePageView(String) 153 | case LivenessView(String) 154 | } 155 | 156 | //#Preview { 157 | // FaceAINaviView() 158 | //} 159 | 160 | 161 | -------------------------------------------------------------------------------- /FaceAISDK_iOS/Localizable.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "🧭 FaceAISDK" : { 5 | 6 | }, 7 | "About us" : { 8 | "localizations" : { 9 | "en" : { 10 | "stringUnit" : { 11 | "state" : "translated", 12 | "value" : "About us" 13 | } 14 | }, 15 | "zh-Hans" : { 16 | "stringUnit" : { 17 | "state" : "translated", 18 | "value" : "关于我们" 19 | } 20 | } 21 | } 22 | }, 23 | "Add Face By Camera" : { 24 | "localizations" : { 25 | "en" : { 26 | "stringUnit" : { 27 | "state" : "translated", 28 | "value" : "Add Face By Camera" 29 | } 30 | }, 31 | "zh-Hans" : { 32 | "stringUnit" : { 33 | "state" : "translated", 34 | "value" : "SDK相机添加人脸" 35 | } 36 | } 37 | } 38 | }, 39 | "Add Face From Album" : { 40 | "localizations" : { 41 | "en" : { 42 | "stringUnit" : { 43 | "state" : "translated", 44 | "value" : "Add Face From Album" 45 | } 46 | }, 47 | "zh-Hans" : { 48 | "stringUnit" : { 49 | "state" : "translated", 50 | "value" : "从相册添加一人脸" 51 | } 52 | } 53 | } 54 | }, 55 | "Confirm" : { 56 | "localizations" : { 57 | "en" : { 58 | "stringUnit" : { 59 | "state" : "translated", 60 | "value" : "Confirm" 61 | } 62 | }, 63 | "zh-Hans" : { 64 | "stringUnit" : { 65 | "state" : "translated", 66 | "value" : "确认" 67 | } 68 | } 69 | } 70 | }, 71 | "Confirm Add Face Tips" : { 72 | "localizations" : { 73 | "en" : { 74 | "stringUnit" : { 75 | "state" : "translated", 76 | "value" : "Confirm is frontal photo" 77 | } 78 | }, 79 | "zh-Hans" : { 80 | "stringUnit" : { 81 | "state" : "translated", 82 | "value" : "请录入无遮挡正脸清晰图" 83 | } 84 | } 85 | } 86 | }, 87 | "Confirm Add Face Title" : { 88 | "localizations" : { 89 | "en" : { 90 | "stringUnit" : { 91 | "state" : "translated", 92 | "value" : "Confirm Add This Face? " 93 | } 94 | }, 95 | "zh-Hans" : { 96 | "stringUnit" : { 97 | "state" : "translated", 98 | "value" : "确认录入次人脸图?" 99 | } 100 | } 101 | } 102 | }, 103 | "Face Verify and Liveness Detection" : { 104 | "localizations" : { 105 | "en" : { 106 | "stringUnit" : { 107 | "state" : "translated", 108 | "value" : "Face Verify and Liveness Detection" 109 | } 110 | }, 111 | "zh-Hans" : { 112 | "stringUnit" : { 113 | "state" : "translated", 114 | "value" : "人脸识别+活体检测" 115 | } 116 | } 117 | } 118 | }, 119 | "Face_Tips_Code_0" : { 120 | "extractionState" : "manual", 121 | "localizations" : { 122 | "en" : { 123 | "stringUnit" : { 124 | "state" : "translated", 125 | "value" : "Keep Face Frontal" 126 | } 127 | }, 128 | "zh-Hans" : { 129 | "stringUnit" : { 130 | "state" : "translated", 131 | "value" : "请正对摄像头" 132 | } 133 | } 134 | } 135 | }, 136 | "Face_Tips_Code_1" : { 137 | "extractionState" : "manual", 138 | "localizations" : { 139 | "en" : { 140 | "stringUnit" : { 141 | "state" : "translated", 142 | "value" : "No Face Detected" 143 | } 144 | }, 145 | "zh-Hans" : { 146 | "stringUnit" : { 147 | "state" : "translated", 148 | "value" : "没有检测到人脸" 149 | } 150 | } 151 | } 152 | }, 153 | "Face_Tips_Code_2" : { 154 | "extractionState" : "manual", 155 | "localizations" : { 156 | "en" : { 157 | "stringUnit" : { 158 | "state" : "translated", 159 | "value" : "Detect Too Many Face" 160 | } 161 | }, 162 | "zh-Hans" : { 163 | "stringUnit" : { 164 | "state" : "translated", 165 | "value" : "检测到多个人脸" 166 | } 167 | } 168 | } 169 | }, 170 | "Face_Tips_Code_3" : { 171 | "extractionState" : "manual", 172 | "localizations" : { 173 | "en" : { 174 | "stringUnit" : { 175 | "state" : "translated", 176 | "value" : "Please Come Closer" 177 | } 178 | }, 179 | "zh-Hans" : { 180 | "stringUnit" : { 181 | "state" : "translated", 182 | "value" : "请靠近一点" 183 | } 184 | } 185 | } 186 | }, 187 | "Face_Tips_Code_4" : { 188 | "extractionState" : "manual", 189 | "localizations" : { 190 | "en" : { 191 | "stringUnit" : { 192 | "state" : "translated", 193 | "value" : "Keep Face Frontal Visible" 194 | } 195 | }, 196 | "zh-Hans" : { 197 | "stringUnit" : { 198 | "state" : "translated", 199 | "value" : "录入中,保持正脸不晃动" 200 | } 201 | } 202 | } 203 | }, 204 | "Face_Tips_Code_5" : { 205 | "extractionState" : "manual", 206 | "localizations" : { 207 | "en" : { 208 | "stringUnit" : { 209 | "state" : "translated", 210 | "value" : "Do not Close Eye" 211 | } 212 | }, 213 | "zh-Hans" : { 214 | "stringUnit" : { 215 | "state" : "translated", 216 | "value" : "不要闭眼睛" 217 | } 218 | } 219 | } 220 | }, 221 | "Face_Tips_Code_6" : { 222 | "extractionState" : "manual", 223 | "localizations" : { 224 | "en" : { 225 | "stringUnit" : { 226 | "state" : "translated", 227 | "value" : "Turn Face Right" 228 | } 229 | }, 230 | "zh-Hans" : { 231 | "stringUnit" : { 232 | "state" : "translated", 233 | "value" : "向右摆正头部" 234 | } 235 | } 236 | } 237 | }, 238 | "Face_Tips_Code_7" : { 239 | "extractionState" : "manual", 240 | "localizations" : { 241 | "en" : { 242 | "stringUnit" : { 243 | "state" : "translated", 244 | "value" : "Turn Face Left" 245 | } 246 | }, 247 | "zh-Hans" : { 248 | "stringUnit" : { 249 | "state" : "translated", 250 | "value" : "向左摆正头部" 251 | } 252 | } 253 | } 254 | }, 255 | "Face_Tips_Code_8" : { 256 | "extractionState" : "manual", 257 | "localizations" : { 258 | "en" : { 259 | "stringUnit" : { 260 | "state" : "translated", 261 | "value" : "Do not Tile Face" 262 | } 263 | }, 264 | "zh-Hans" : { 265 | "stringUnit" : { 266 | "state" : "translated", 267 | "value" : "不要歪头" 268 | } 269 | } 270 | } 271 | }, 272 | "Face_Tips_Code_9" : { 273 | "extractionState" : "manual", 274 | "localizations" : { 275 | "en" : { 276 | "stringUnit" : { 277 | "state" : "translated", 278 | "value" : "Turn Face Up" 279 | } 280 | }, 281 | "zh-Hans" : { 282 | "stringUnit" : { 283 | "state" : "translated", 284 | "value" : "向上摆正头部" 285 | } 286 | } 287 | } 288 | }, 289 | "Face_Tips_Code_10" : { 290 | "extractionState" : "manual", 291 | "localizations" : { 292 | "en" : { 293 | "stringUnit" : { 294 | "state" : "translated", 295 | "value" : "Turn Face Down" 296 | } 297 | }, 298 | "zh-Hans" : { 299 | "stringUnit" : { 300 | "state" : "translated", 301 | "value" : "向下摆正头部" 302 | } 303 | } 304 | } 305 | }, 306 | "Face_Tips_Code_11" : { 307 | "extractionState" : "manual", 308 | "localizations" : { 309 | "en" : { 310 | "stringUnit" : { 311 | "state" : "translated", 312 | "value" : "Confirm Add Face" 313 | } 314 | }, 315 | "zh-Hans" : { 316 | "stringUnit" : { 317 | "state" : "translated", 318 | "value" : "人脸采集确认中" 319 | } 320 | } 321 | } 322 | }, 323 | "Face_Tips_Code_12" : { 324 | "extractionState" : "manual", 325 | "localizations" : { 326 | "en" : { 327 | "stringUnit" : { 328 | "state" : "translated", 329 | "value" : " " 330 | } 331 | }, 332 | "zh-Hans" : { 333 | "stringUnit" : { 334 | "state" : "translated", 335 | "value" : " " 336 | } 337 | } 338 | } 339 | }, 340 | "Face_Tips_Code_13" : { 341 | "extractionState" : "manual", 342 | "localizations" : { 343 | "en" : { 344 | "stringUnit" : { 345 | "state" : "translated", 346 | "value" : "Too Small Face" 347 | } 348 | }, 349 | "zh-Hans" : { 350 | "stringUnit" : { 351 | "state" : "translated", 352 | "value" : "人脸太小了" 353 | } 354 | } 355 | } 356 | }, 357 | "Face_Tips_Code_31" : { 358 | "extractionState" : "manual", 359 | "localizations" : { 360 | "en" : { 361 | "stringUnit" : { 362 | "state" : "translated", 363 | "value" : "Face Image Not Found " 364 | } 365 | }, 366 | "zh-Hans" : { 367 | "stringUnit" : { 368 | "state" : "translated", 369 | "value" : "没有找到对应的人脸底片" 370 | } 371 | } 372 | } 373 | }, 374 | "Face_Tips_Code_32" : { 375 | "extractionState" : "manual", 376 | "localizations" : { 377 | "en" : { 378 | "stringUnit" : { 379 | "state" : "translated", 380 | "value" : "Face Image Dispose Failed" 381 | } 382 | }, 383 | "zh-Hans" : { 384 | "stringUnit" : { 385 | "state" : "translated", 386 | "value" : "人脸底片处理失败" 387 | } 388 | } 389 | } 390 | }, 391 | "Face_Tips_Code_33" : { 392 | "extractionState" : "manual", 393 | "localizations" : { 394 | "en" : { 395 | "stringUnit" : { 396 | "state" : "translated", 397 | "value" : "SDK Error" 398 | } 399 | }, 400 | "zh-Hans" : { 401 | "stringUnit" : { 402 | "state" : "translated", 403 | "value" : "SDK 内部错误" 404 | } 405 | } 406 | } 407 | }, 408 | "Face_Tips_Code_34" : { 409 | "extractionState" : "manual", 410 | "localizations" : { 411 | "en" : { 412 | "stringUnit" : { 413 | "state" : "translated", 414 | "value" : "Verify Success" 415 | } 416 | }, 417 | "zh-Hans" : { 418 | "stringUnit" : { 419 | "state" : "translated", 420 | "value" : "人脸识别检验成功" 421 | } 422 | } 423 | } 424 | }, 425 | "Face_Tips_Code_35" : { 426 | "extractionState" : "manual", 427 | "localizations" : { 428 | "en" : { 429 | "stringUnit" : { 430 | "state" : "translated", 431 | "value" : "Verify Failed" 432 | } 433 | }, 434 | "zh-Hans" : { 435 | "stringUnit" : { 436 | "state" : "translated", 437 | "value" : "人脸相似度低于阈值" 438 | } 439 | } 440 | } 441 | }, 442 | "Face_Tips_Code_36" : { 443 | "extractionState" : "manual", 444 | "localizations" : { 445 | "en" : { 446 | "stringUnit" : { 447 | "state" : "translated", 448 | "value" : "Liveness Complete" 449 | } 450 | }, 451 | "zh-Hans" : { 452 | "stringUnit" : { 453 | "state" : "translated", 454 | "value" : "活体检测完成" 455 | } 456 | } 457 | } 458 | }, 459 | "Face_Tips_Code_37" : { 460 | "extractionState" : "manual", 461 | "localizations" : { 462 | "en" : { 463 | "stringUnit" : { 464 | "state" : "translated", 465 | "value" : "Liveness Timeout" 466 | } 467 | }, 468 | "zh-Hans" : { 469 | "stringUnit" : { 470 | "state" : "translated", 471 | "value" : "动作活体检验超时" 472 | } 473 | } 474 | } 475 | }, 476 | "Face_Tips_Code_38" : { 477 | "extractionState" : "manual", 478 | "localizations" : { 479 | "en" : { 480 | "stringUnit" : { 481 | "state" : "translated", 482 | "value" : "No Face Detected Multi Time" 483 | } 484 | }, 485 | "zh-Hans" : { 486 | "stringUnit" : { 487 | "state" : "translated", 488 | "value" : "多次切换人脸或检测失败" 489 | } 490 | } 491 | } 492 | }, 493 | "Face_Tips_Code_41" : { 494 | "extractionState" : "manual", 495 | "localizations" : { 496 | "en" : { 497 | "stringUnit" : { 498 | "state" : "translated", 499 | "value" : "Open Mouse" 500 | } 501 | }, 502 | "zh-Hans" : { 503 | "stringUnit" : { 504 | "state" : "translated", 505 | "value" : "请张张嘴" 506 | } 507 | } 508 | } 509 | }, 510 | "Face_Tips_Code_42" : { 511 | "extractionState" : "manual", 512 | "localizations" : { 513 | "en" : { 514 | "stringUnit" : { 515 | "state" : "translated", 516 | "value" : "Please Smile" 517 | } 518 | }, 519 | "zh-Hans" : { 520 | "stringUnit" : { 521 | "state" : "translated", 522 | "value" : "请微笑" 523 | } 524 | } 525 | } 526 | }, 527 | "Face_Tips_Code_43" : { 528 | "extractionState" : "manual", 529 | "localizations" : { 530 | "en" : { 531 | "stringUnit" : { 532 | "state" : "translated", 533 | "value" : "Please Blink" 534 | } 535 | }, 536 | "zh-Hans" : { 537 | "stringUnit" : { 538 | "state" : "translated", 539 | "value" : "请眨眼" 540 | } 541 | } 542 | } 543 | }, 544 | "Face_Tips_Code_44" : { 545 | "extractionState" : "manual", 546 | "localizations" : { 547 | "en" : { 548 | "stringUnit" : { 549 | "state" : "translated", 550 | "value" : "Please Shake Head" 551 | } 552 | }, 553 | "zh-Hans" : { 554 | "stringUnit" : { 555 | "state" : "translated", 556 | "value" : "请摇头" 557 | } 558 | } 559 | } 560 | }, 561 | "Face_Tips_Code_45" : { 562 | "extractionState" : "manual", 563 | "localizations" : { 564 | "en" : { 565 | "stringUnit" : { 566 | "state" : "translated", 567 | "value" : "Please Nod Head" 568 | } 569 | }, 570 | "zh-Hans" : { 571 | "stringUnit" : { 572 | "state" : "translated", 573 | "value" : "请点头" 574 | } 575 | } 576 | } 577 | }, 578 | "I Know" : { 579 | "extractionState" : "stale", 580 | "localizations" : { 581 | "en" : { 582 | "stringUnit" : { 583 | "state" : "translated", 584 | "value" : "I Know" 585 | } 586 | }, 587 | "zh-Hans" : { 588 | "stringUnit" : { 589 | "state" : "translated", 590 | "value" : "知道了" 591 | } 592 | } 593 | } 594 | }, 595 | "is Face Feature Exist" : { 596 | "localizations" : { 597 | "zh-Hans" : { 598 | "stringUnit" : { 599 | "state" : "translated", 600 | "value" : "人脸特征值是否存在" 601 | } 602 | } 603 | } 604 | }, 605 | "ONLY Motion Liveness Detection" : { 606 | "localizations" : { 607 | "en" : { 608 | "stringUnit" : { 609 | "state" : "translated", 610 | "value" : "ONLY Motion Liveness Detection" 611 | } 612 | }, 613 | "zh-Hans" : { 614 | "stringUnit" : { 615 | "state" : "translated", 616 | "value" : "仅动作活体检测" 617 | } 618 | } 619 | } 620 | }, 621 | "Retry" : { 622 | "localizations" : { 623 | "en" : { 624 | "stringUnit" : { 625 | "state" : "translated", 626 | "value" : "Retry" 627 | } 628 | }, 629 | "zh-Hans" : { 630 | "stringUnit" : { 631 | "state" : "translated", 632 | "value" : "重试" 633 | } 634 | } 635 | } 636 | }, 637 | "保存人脸数据" : { 638 | 639 | }, 640 | "请从相册中选择一张图片" : { 641 | 642 | }, 643 | "选择图片" : { 644 | 645 | } 646 | }, 647 | "version" : "1.0" 648 | } -------------------------------------------------------------------------------- /FaceAISDK_iOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 60; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7C600D4F2EDEB8A3005EEEDD /* CustomToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C600D4E2EDEB8A3005EEEDD /* CustomToastView.swift */; }; 11 | 7CD054CE2EDE7E6300EA3E37 /* FaceAINaviView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CD054C72EDE7E6300EA3E37 /* FaceAINaviView.swift */; }; 12 | 7CD054D02EDE7E6300EA3E37 /* AddFaceByUIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CD054C92EDE7E6300EA3E37 /* AddFaceByUIImage.swift */; }; 13 | 7CD054D12EDE7E6300EA3E37 /* AddFaceByCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CD054CA2EDE7E6300EA3E37 /* AddFaceByCamera.swift */; }; 14 | 7CD054D22EDE7E6300EA3E37 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 7CD054CB2EDE7E6300EA3E37 /* Localizable.xcstrings */; }; 15 | 7CD054D32EDE7E6300EA3E37 /* VerifyFaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CD054CC2EDE7E6300EA3E37 /* VerifyFaceView.swift */; }; 16 | 7CD054D42EDE7E6300EA3E37 /* LivenessDetectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CD054CD2EDE7E6300EA3E37 /* LivenessDetectView.swift */; }; 17 | 7CFB912F2EDE7D5F00F01A21 /* FaceAISDK_iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CFB912E2EDE7D5F00F01A21 /* FaceAISDK_iOSApp.swift */; }; 18 | 7CFB91332EDE7D6200F01A21 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7CFB91322EDE7D6200F01A21 /* Assets.xcassets */; }; 19 | A5E65290CCD896B3F7C285AA /* Pods_FaceAISDK_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EE5EDF11DB0DDBA7F1E58BD /* Pods_FaceAISDK_iOS.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | 3055E22F49718251F69290DD /* Pods-FaceAISDK_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FaceAISDK_iOS.release.xcconfig"; path = "Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS.release.xcconfig"; sourceTree = ""; }; 24 | 4EE5EDF11DB0DDBA7F1E58BD /* Pods_FaceAISDK_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FaceAISDK_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 7C600D4E2EDEB8A3005EEEDD /* CustomToastView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomToastView.swift; sourceTree = ""; }; 26 | 7CD054C72EDE7E6300EA3E37 /* FaceAINaviView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaceAINaviView.swift; sourceTree = ""; }; 27 | 7CD054C92EDE7E6300EA3E37 /* AddFaceByUIImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFaceByUIImage.swift; sourceTree = ""; }; 28 | 7CD054CA2EDE7E6300EA3E37 /* AddFaceByCamera.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFaceByCamera.swift; sourceTree = ""; }; 29 | 7CD054CB2EDE7E6300EA3E37 /* Localizable.xcstrings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 30 | 7CD054CC2EDE7E6300EA3E37 /* VerifyFaceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifyFaceView.swift; sourceTree = ""; }; 31 | 7CD054CD2EDE7E6300EA3E37 /* LivenessDetectView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LivenessDetectView.swift; sourceTree = ""; }; 32 | 7CFB912B2EDE7D5F00F01A21 /* FaceAISDK_iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FaceAISDK_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 7CFB912E2EDE7D5F00F01A21 /* FaceAISDK_iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaceAISDK_iOSApp.swift; sourceTree = ""; }; 34 | 7CFB91322EDE7D6200F01A21 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 35 | FBCEA53D3F0A9191F9E0702C /* Pods-FaceAISDK_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FaceAISDK_iOS.debug.xcconfig"; path = "Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS.debug.xcconfig"; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 7CFB91282EDE7D5F00F01A21 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | A5E65290CCD896B3F7C285AA /* Pods_FaceAISDK_iOS.framework in Frameworks */, 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 5F578C59EB0DFE4CB1249745 /* Frameworks */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 4EE5EDF11DB0DDBA7F1E58BD /* Pods_FaceAISDK_iOS.framework */, 54 | ); 55 | name = Frameworks; 56 | sourceTree = ""; 57 | }; 58 | 7CFB91222EDE7D5F00F01A21 = { 59 | isa = PBXGroup; 60 | children = ( 61 | 7CFB912D2EDE7D5F00F01A21 /* FaceAISDK_iOS */, 62 | 7CFB912C2EDE7D5F00F01A21 /* Products */, 63 | CA9698F986369A4029CA9251 /* Pods */, 64 | 5F578C59EB0DFE4CB1249745 /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 7CFB912C2EDE7D5F00F01A21 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 7CFB912B2EDE7D5F00F01A21 /* FaceAISDK_iOS.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 7CFB912D2EDE7D5F00F01A21 /* FaceAISDK_iOS */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 7CD054CA2EDE7E6300EA3E37 /* AddFaceByCamera.swift */, 80 | 7C600D4E2EDEB8A3005EEEDD /* CustomToastView.swift */, 81 | 7CD054C92EDE7E6300EA3E37 /* AddFaceByUIImage.swift */, 82 | 7CD054C72EDE7E6300EA3E37 /* FaceAINaviView.swift */, 83 | 7CD054CD2EDE7E6300EA3E37 /* LivenessDetectView.swift */, 84 | 7CD054CB2EDE7E6300EA3E37 /* Localizable.xcstrings */, 85 | 7CD054CC2EDE7E6300EA3E37 /* VerifyFaceView.swift */, 86 | 7CFB912E2EDE7D5F00F01A21 /* FaceAISDK_iOSApp.swift */, 87 | 7CFB91322EDE7D6200F01A21 /* Assets.xcassets */, 88 | ); 89 | path = FaceAISDK_iOS; 90 | sourceTree = ""; 91 | }; 92 | CA9698F986369A4029CA9251 /* Pods */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | FBCEA53D3F0A9191F9E0702C /* Pods-FaceAISDK_iOS.debug.xcconfig */, 96 | 3055E22F49718251F69290DD /* Pods-FaceAISDK_iOS.release.xcconfig */, 97 | ); 98 | path = Pods; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 7CFB912A2EDE7D5F00F01A21 /* FaceAISDK_iOS */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 7CFB91392EDE7D6200F01A21 /* Build configuration list for PBXNativeTarget "FaceAISDK_iOS" */; 107 | buildPhases = ( 108 | FC74257BD7D99220866D6C00 /* [CP] Check Pods Manifest.lock */, 109 | 7CFB91272EDE7D5F00F01A21 /* Sources */, 110 | 7CFB91282EDE7D5F00F01A21 /* Frameworks */, 111 | 7CFB91292EDE7D5F00F01A21 /* Resources */, 112 | B8776F7226FF751A1E299440 /* [CP] Embed Pods Frameworks */, 113 | EF18BB250E6EC529109F3815 /* [CP] Copy Pods Resources */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = FaceAISDK_iOS; 120 | productName = FaceAISDK_iOS; 121 | productReference = 7CFB912B2EDE7D5F00F01A21 /* FaceAISDK_iOS.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 7CFB91232EDE7D5F00F01A21 /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | BuildIndependentTargetsInParallel = 1; 131 | LastSwiftUpdateCheck = 1520; 132 | LastUpgradeCheck = 1520; 133 | TargetAttributes = { 134 | 7CFB912A2EDE7D5F00F01A21 = { 135 | CreatedOnToolsVersion = 15.2; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 7CFB91262EDE7D5F00F01A21 /* Build configuration list for PBXProject "FaceAISDK_iOS" */; 140 | compatibilityVersion = "Xcode 15.0"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 7CFB91222EDE7D5F00F01A21; 148 | productRefGroup = 7CFB912C2EDE7D5F00F01A21 /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 7CFB912A2EDE7D5F00F01A21 /* FaceAISDK_iOS */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 7CFB91292EDE7D5F00F01A21 /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 7CD054D22EDE7E6300EA3E37 /* Localizable.xcstrings in Resources */, 163 | 7CFB91332EDE7D6200F01A21 /* Assets.xcassets in Resources */, 164 | ); 165 | runOnlyForDeploymentPostprocessing = 0; 166 | }; 167 | /* End PBXResourcesBuildPhase section */ 168 | 169 | /* Begin PBXShellScriptBuildPhase section */ 170 | B8776F7226FF751A1E299440 /* [CP] Embed Pods Frameworks */ = { 171 | isa = PBXShellScriptBuildPhase; 172 | buildActionMask = 2147483647; 173 | files = ( 174 | ); 175 | inputFileListPaths = ( 176 | "${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", 177 | ); 178 | name = "[CP] Embed Pods Frameworks"; 179 | outputFileListPaths = ( 180 | "${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-frameworks.sh\"\n"; 185 | showEnvVarsInLog = 0; 186 | }; 187 | EF18BB250E6EC529109F3815 /* [CP] Copy Pods Resources */ = { 188 | isa = PBXShellScriptBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | ); 192 | inputFileListPaths = ( 193 | "${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-resources-${CONFIGURATION}-input-files.xcfilelist", 194 | ); 195 | name = "[CP] Copy Pods Resources"; 196 | outputFileListPaths = ( 197 | "${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-resources-${CONFIGURATION}-output-files.xcfilelist", 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | shellPath = /bin/sh; 201 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FaceAISDK_iOS/Pods-FaceAISDK_iOS-resources.sh\"\n"; 202 | showEnvVarsInLog = 0; 203 | }; 204 | FC74257BD7D99220866D6C00 /* [CP] Check Pods Manifest.lock */ = { 205 | isa = PBXShellScriptBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | inputFileListPaths = ( 210 | ); 211 | inputPaths = ( 212 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 213 | "${PODS_ROOT}/Manifest.lock", 214 | ); 215 | name = "[CP] Check Pods Manifest.lock"; 216 | outputFileListPaths = ( 217 | ); 218 | outputPaths = ( 219 | "$(DERIVED_FILE_DIR)/Pods-FaceAISDK_iOS-checkManifestLockResult.txt", 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | shellPath = /bin/sh; 223 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 224 | showEnvVarsInLog = 0; 225 | }; 226 | /* End PBXShellScriptBuildPhase section */ 227 | 228 | /* Begin PBXSourcesBuildPhase section */ 229 | 7CFB91272EDE7D5F00F01A21 /* Sources */ = { 230 | isa = PBXSourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 7CFB912F2EDE7D5F00F01A21 /* FaceAISDK_iOSApp.swift in Sources */, 234 | 7C600D4F2EDEB8A3005EEEDD /* CustomToastView.swift in Sources */, 235 | 7CD054D02EDE7E6300EA3E37 /* AddFaceByUIImage.swift in Sources */, 236 | 7CD054D42EDE7E6300EA3E37 /* LivenessDetectView.swift in Sources */, 237 | 7CD054D32EDE7E6300EA3E37 /* VerifyFaceView.swift in Sources */, 238 | 7CD054CE2EDE7E6300EA3E37 /* FaceAINaviView.swift in Sources */, 239 | 7CD054D12EDE7E6300EA3E37 /* AddFaceByCamera.swift in Sources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | /* End PBXSourcesBuildPhase section */ 244 | 245 | /* Begin XCBuildConfiguration section */ 246 | 7CFB91372EDE7D6200F01A21 /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 251 | CLANG_ANALYZER_NONNULL = YES; 252 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 253 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_ENABLE_OBJC_WEAK = YES; 257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 258 | CLANG_WARN_BOOL_CONVERSION = YES; 259 | CLANG_WARN_COMMA = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 272 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 273 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 274 | CLANG_WARN_STRICT_PROTOTYPES = YES; 275 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 276 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 277 | CLANG_WARN_UNREACHABLE_CODE = YES; 278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 279 | COPY_PHASE_STRIP = NO; 280 | DEBUG_INFORMATION_FORMAT = dwarf; 281 | ENABLE_STRICT_OBJC_MSGSEND = YES; 282 | ENABLE_TESTABILITY = YES; 283 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 284 | GCC_C_LANGUAGE_STANDARD = gnu17; 285 | GCC_DYNAMIC_NO_PIC = NO; 286 | GCC_NO_COMMON_BLOCKS = YES; 287 | GCC_OPTIMIZATION_LEVEL = 0; 288 | GCC_PREPROCESSOR_DEFINITIONS = ( 289 | "DEBUG=1", 290 | "$(inherited)", 291 | ); 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 299 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 300 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 301 | MTL_FAST_MATH = YES; 302 | ONLY_ACTIVE_ARCH = YES; 303 | SDKROOT = iphoneos; 304 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 305 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 306 | }; 307 | name = Debug; 308 | }; 309 | 7CFB91382EDE7D6200F01A21 /* Release */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | ALWAYS_SEARCH_USER_PATHS = NO; 313 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_ENABLE_OBJC_WEAK = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_COMMA = YES; 323 | CLANG_WARN_CONSTANT_CONVERSION = YES; 324 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 325 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 326 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 327 | CLANG_WARN_EMPTY_BODY = YES; 328 | CLANG_WARN_ENUM_CONVERSION = YES; 329 | CLANG_WARN_INFINITE_RECURSION = YES; 330 | CLANG_WARN_INT_CONVERSION = YES; 331 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 333 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 334 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 335 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 340 | CLANG_WARN_UNREACHABLE_CODE = YES; 341 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 344 | ENABLE_NS_ASSERTIONS = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 347 | GCC_C_LANGUAGE_STANDARD = gnu17; 348 | GCC_NO_COMMON_BLOCKS = YES; 349 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 351 | GCC_WARN_UNDECLARED_SELECTOR = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 353 | GCC_WARN_UNUSED_FUNCTION = YES; 354 | GCC_WARN_UNUSED_VARIABLE = YES; 355 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 356 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 357 | MTL_ENABLE_DEBUG_INFO = NO; 358 | MTL_FAST_MATH = YES; 359 | SDKROOT = iphoneos; 360 | SWIFT_COMPILATION_MODE = wholemodule; 361 | VALIDATE_PRODUCT = YES; 362 | }; 363 | name = Release; 364 | }; 365 | 7CFB913A2EDE7D6200F01A21 /* Debug */ = { 366 | isa = XCBuildConfiguration; 367 | baseConfigurationReference = FBCEA53D3F0A9191F9E0702C /* Pods-FaceAISDK_iOS.debug.xcconfig */; 368 | buildSettings = { 369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 370 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 371 | CODE_SIGN_STYLE = Automatic; 372 | CURRENT_PROJECT_VERSION = 2; 373 | DEVELOPMENT_ASSET_PATHS = "\"FaceAISDK_iOS/Preview Content\""; 374 | DEVELOPMENT_TEAM = G35M5X479Y; 375 | ENABLE_PREVIEWS = YES; 376 | GENERATE_INFOPLIST_FILE = YES; 377 | INFOPLIST_KEY_CFBundleDisplayName = FaceAISDK; 378 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; 379 | INFOPLIST_KEY_NSCameraUsageDescription = "人脸识别需要通过摄像头进行验证"; 380 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 381 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 382 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 383 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 384 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 385 | LD_RUNPATH_SEARCH_PATHS = ( 386 | "$(inherited)", 387 | "@executable_path/Frameworks", 388 | ); 389 | MARKETING_VERSION = 2.0; 390 | PRODUCT_BUNDLE_IDENTIFIER = com.facesdk.demo; 391 | PRODUCT_NAME = "$(TARGET_NAME)"; 392 | SWIFT_EMIT_LOC_STRINGS = YES; 393 | SWIFT_VERSION = 5.0; 394 | TARGETED_DEVICE_FAMILY = "1,2"; 395 | }; 396 | name = Debug; 397 | }; 398 | 7CFB913B2EDE7D6200F01A21 /* Release */ = { 399 | isa = XCBuildConfiguration; 400 | baseConfigurationReference = 3055E22F49718251F69290DD /* Pods-FaceAISDK_iOS.release.xcconfig */; 401 | buildSettings = { 402 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 403 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 404 | CODE_SIGN_STYLE = Automatic; 405 | CURRENT_PROJECT_VERSION = 2; 406 | DEVELOPMENT_ASSET_PATHS = "\"FaceAISDK_iOS/Preview Content\""; 407 | DEVELOPMENT_TEAM = G35M5X479Y; 408 | ENABLE_PREVIEWS = YES; 409 | GENERATE_INFOPLIST_FILE = YES; 410 | INFOPLIST_KEY_CFBundleDisplayName = FaceAISDK; 411 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; 412 | INFOPLIST_KEY_NSCameraUsageDescription = "人脸识别需要通过摄像头进行验证"; 413 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 414 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 415 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 416 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 417 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 418 | LD_RUNPATH_SEARCH_PATHS = ( 419 | "$(inherited)", 420 | "@executable_path/Frameworks", 421 | ); 422 | MARKETING_VERSION = 2.0; 423 | PRODUCT_BUNDLE_IDENTIFIER = com.facesdk.demo; 424 | PRODUCT_NAME = "$(TARGET_NAME)"; 425 | SWIFT_EMIT_LOC_STRINGS = YES; 426 | SWIFT_VERSION = 5.0; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Release; 430 | }; 431 | /* End XCBuildConfiguration section */ 432 | 433 | /* Begin XCConfigurationList section */ 434 | 7CFB91262EDE7D5F00F01A21 /* Build configuration list for PBXProject "FaceAISDK_iOS" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | 7CFB91372EDE7D6200F01A21 /* Debug */, 438 | 7CFB91382EDE7D6200F01A21 /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | 7CFB91392EDE7D6200F01A21 /* Build configuration list for PBXNativeTarget "FaceAISDK_iOS" */ = { 444 | isa = XCConfigurationList; 445 | buildConfigurations = ( 446 | 7CFB913A2EDE7D6200F01A21 /* Debug */, 447 | 7CFB913B2EDE7D6200F01A21 /* Release */, 448 | ); 449 | defaultConfigurationIsVisible = 0; 450 | defaultConfigurationName = Release; 451 | }; 452 | /* End XCConfigurationList section */ 453 | }; 454 | rootObject = 7CFB91232EDE7D5F00F01A21 /* Project object */; 455 | } 456 | --------------------------------------------------------------------------------