[SwiftUI 知识碎片] 在 SwiftUI 中使用 Touch ID 和 Face ID

1,175 阅读3分钟
译自 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 个步骤:

  1. 创建 LAContext 实例,以便我们可以查询生物特征识别功能的可用性,以及执行识别检测。
  2. 之所以要检查生物特征识别功能是否存在,是因为某些 iOS 设备例如 iPod touch 没有 Touch ID ,也没有 Face ID。
  3. 如果可以进行生物特征识别,我们发起实际的识别请求,并传入一个闭包,供识别完成时调用。
  4. 不管识别是否通过,我们的完成闭包代码都会被调用。因为它不是在主线程执行,所以我们需要把 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及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~