SwiftUI: 使用 Touch ID 和 Face I
苹果绝大多数设备都以生物识别身份验证为标准,这意味着它们使用指纹和面部识别来解锁。我们也可以使用此功能,这意味着我们可以确保仅当有效用户解锁后才能读取敏感数据。
这是另一个Objective-C API,但与SwiftUI一起使用时有仅仅有一小点不愉快,这比到目前为止我们看过的其他框架要好。
在编写任何代码之前,您需要向Info.plist
文件中添加一个新 key,向用户说明为什么要访问 Face ID。由于只有Apple知道的原因,我们在代码中传递了Touch ID请求原因,而在Info.plist
中也要传递 Face ID 请求的原因。
立即打开Info.plist
,右键单击空白,然后选择“Add Row”。滚动键列表,直到找到“Privacy - Face ID Usage Description”,并为其赋予值“我们需要解锁您的数据”。
现在回到ContentView.swift,并在文件顶部附近添加以下导入:
import LocalAuthentication
好的,我们已经准备好使用生物识别了。我之前提到过,这“一点点令人不快”,这就是原因:Swift开发人员使用 Error
协议表示运行时发生的错误,但是 Objective-C 使用一个称为NSError
的特殊类。因为这是一个Objective-C API,所以我们需要使用NSError
来处理问题,并像常规inout
参数一样使用&
传递它。
我们将编写一个authenticate()
方法,将所有生物特征功能隔离在一个地方。为此,需要四个步骤:
- 创建
LAContext
实例,这使我们可以查询生物识别状态并执行身份验证检查。 - 询问上下文是否能够执行生物特征认证——这很重要,因为iPod touch 既没有 Touch ID 也没有 Face ID。
- 如果可以进行生物识别,那么我们将启动实际的身份验证请求,并传递一个闭包以在身份验证完成时运行。
- 当用户通过身份验证或未通过身份验证时,我们的完成关闭将被调用并告诉我们它是否有效,如果不是,那么错误是什么。该闭包将从主线程中调用,因此我们需要将所有与UI相关的工作推回主线程。
请继续并将此方法添加到ContentView
:
func authenticate() {
let context = LAContext()
var error: NSError?
// 检查生物特征认证是否可用
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 可用,所以继续使用它
let reason = "我们需要解锁您的数据"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
// 身份验证现已完成
DispatchQueue.main.async {
if success {
// 认证成功
} else {
// 发生的异常
}
}
}
} else {
// 没有生物识别
}
}
该方法本身不会执行任何操作,因为它根本没有连接到SwiftUI。为了解决这个问题,我们需要添加一些状态,我们可以在身份验证成功时进行调整,还可以使用onAppear()
修饰符来触发身份验证。
因此,首先将此属性添加到ContentView
:
@State private var isUnlocked = false
这个简单的布尔值将存储应用程序是否显示其受保护的数据,因此当身份验证成功时,我们会将其设置为true。用其替换注释 // 认证成功
:
self.isUnlocked = true
最后,我们可以显示当前身份验证状态并在 body
属性内开始身份验证过程,如下所示:
VStack {
if self.isUnlocked {
Text("Unlocked")
} else {
Text("Locked")
}
}
.onAppear(perform: authenticate)
如果您运行该应用,则很有可能会看到“Locked”,而没有其他显示。这是因为默认情况下,模拟器未启用生物识别功能,并且我们未提供任何错误消息,因此它会自动失败。
要将Face ID用于测试驱动器,请转到“ Hardware/Features”菜单,然后选择 Face ID > Enrolled,然后再次启动该应用程序。这次您应该看到出现Face ID提示,并且可以通过返回到“硬件”菜单并选择“ Face ID”>“匹配的面部”或“不匹配的面部”来触发成功或失败的身份验证。
一切都很好,您应该会看到Face ID提示消失了,下面是“Unlocked”文本视图——我们的应用程序已检测到身份验证,并且可以使用。
- 【设计模式】—— 装饰模式Decorator
- 【设计模式】—— 组合模式Composite
- 【设计模式】—— 桥接模式Bridge
- 【插件开发】—— 1 Eclipse插件开发导盲
- 【插件开发】—— 4 SWT编程须知
- 【插件开发】—— 5 SWT控件以及布局使用
- 【插件开发】—— 6 SWT 复杂控件使用以及布局
- 【插件开发】—— 7 SWT布局详解,不能再详细了!
- 【插件开发】—— 8 IPreferenceStore,插件的键/值存储!
- 【插件开发】—— 9 编辑器代码分块着色-高亮显示!
- 【插件开发】—— 10 JFace开发详解
- 【插件开发】—— 12 GEF入门
- 【插件开发】—— 13 GEF双击模型事件
- 给博客添加节日雪花
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Kubeflow 部署采坑记录
- Kubeflow v0.6.0 部署采坑记录
- Kubeflow Pipeline 部署记录
- Kubeflow Pipeline - 上传一个 Pipeline
- Kubeflow Pipeline - 构建自定义的 Workflow
- R语言入门之变量重编码与重命名
- Kubeflow Pipeline - 构建一个机器学习 Workflow
- Git 如何压缩 commit
- How go build works
- 网状Meta分析之R语言‘gemtc’包实战(3)
- 关于 K8S API Resources: Group 和 Version 该怎么写
- ZooKeeper 的应用场景
- 在 K8S 部署一个 Spark History Server - 篇3
- Go 学习笔记-1
- Tensorflow-gpu 运行在 cpu 母机的问题