译自 Using Touch ID and Face ID with SwiftUI
更多内容欢迎关注公众号 「Swift花园」
绝大部分 Apple 的设备都有生物识别认证的手段,包括用指纹和面部识别来解锁。这个功能也对开发者开放,也就是说,我们可以利用它来确保敏感数据只能被合法的用户读取。
这又是另一个 Objective-C 的 API,但和 SwiftUI 一起使用它只是令人稍感不快,相比目前为止我们研究过的其他框架要好。
在我们编写代码之前,你需要在你的 Info.plist 文件里添加一个新的键,向用户解释为什么你需要访问 Face ID 。Touch ID 请求的理由在代码里,而 Face ID 请求的理由是放在 Info.plist 里。
打开 Info.plist ,在空白的地方右键,选择 Add Row 。滚动列表直到你找到 “Privacy - Face ID Usage Description” ,然后填写值 “We need to unlock your data.”
回到 ContentView.swift ,在文件头添加这一行:
import LocalAuthentication好了,现在可以使用生物特征识别的 API 了。前面提到用法有点麻烦,原因是这样的:Swift 开发者用 Error 协议来代表运行时的各种错误,但是 Objective-C 用一个叫 NSError 的类来处理。因为这是一个 Objective-C API ,我们需要用 NSError 来处理问题,用 & 来传这个值,就像一个 inout 参数。
我们要写一个 authenticate() 方法,把所有生物特征鉴权的代码放在那里。 一共需要 4 个步骤:
- 创建
LAContext实例,以便我们可以查询生物特征识别功能的可用性,以及执行识别检测。 - 之所以要检查生物特征识别功能是否存在,是因为某些 iOS 设备例如 iPod touch 没有 Touch ID ,也没有 Face ID。
- 如果可以进行生物特征识别,我们发起实际的识别请求,并传入一个闭包,供识别完成时调用。
- 不管识别是否通过,我们的完成闭包代码都会被调用。因为它不是在主线程执行,所以我们需要把 UI 相关的工作推回主线程执行。
把下面的方法加到 ContentView:
func authenticate() {
let context = LAContext()
var error: NSError?
// 检查是否可以进行生物特征识别
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 如果可以,执行识别
let reason = "We need to unlock your data."
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
// 鉴权完成
DispatchQueue.main.async {
if success {
// 鉴权成功
} else {
// 鉴权失败
}
}
}
} else {
// 没有生物指纹识别功能
}
}这个方法自身还做不了什么事,因为还没被连接到 SwiftUI 。为了修正这个问题,我们添加一个状态,当鉴权完成时修改状态。并且在 onAppear()中附上这个鉴权方法。
@State private var isUnlocked = false这个状态决定是否展示数据,如果鉴权成功就变为 true 。把上面的 // 鉴权成功 注释换成下面的代码:
self.isUnlocked = true最后,在 body 属性里添加初始 UI ,像这样:
VStack {
if self.isUnlocked {
Text("Unlocked")
} else {
Text("Locked")
}
}
.onAppear(perform: authenticate)如果你是在模拟器里运行 app ,你会看到 “Locked” 。这是因为模拟器默认是没有配置生物特征识别的,而我们也没有打印错误信息,所以就默默失败了。
为了测试 Face ID ,需要到 Hardware 菜单选择 Face ID > Enrolled,然后重新启动 app 。这样你就会看到 Face ID 提示,可以通过 Hardware 菜单里选择 Face ID > Matching Face 或者 Non-matching Face 来通过检测或者失败。
当 Face ID 检测通过时,我们 app 的实际功能就可以使用了。
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~