0Pricing
Swift Academy · 课时

生物识别身份验证

使用 Face ID 和 Touch ID 验证用户身份。

生物识别身份验证 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

使用 LocalAuthentication 进行生物识别

面容 ID 和触控 ID 允许用户无需输入密码即可证明自己的身份。LocalAuthentication 框架通过 LAContext 提供此功能;它会评估身份验证策略,并告知您用户是否通过了验证。

import LocalAuthentication
let context = LAContext()
// One LAContext object drives a single auth attempt

先检查可用性

请始终在显示提示之前调用 canEvaluatePolicy。设备可能没有生物识别硬件,用户可能尚未录入生物识别信息,或者生物识别功能可能已被锁定。此方法会返回一个布尔值;如果失败,还会返回解释原因的错误。

import LocalAuthentication
func canUseBiometrics() -> Bool {
    let context = LAContext()
    var error: NSError?
    return context.canEvaluatePolicy(
        .deviceOwnerAuthenticationWithBiometrics,
        error: &error)
}

两种策略

.deviceOwnerAuthenticationWithBiometrics 要求使用面容 ID 或触控 ID,并且不提供密码回退。.deviceOwnerAuthentication 会优先尝试生物识别,但会回退到设备密码。请根据是否接受密码验证来选择策略。

import LocalAuthentication
// Biometrics only (no passcode fallback):
let strict = LAPolicy.deviceOwnerAuthenticationWithBiometrics
// Biometrics with passcode fallback:
let lenient = LAPolicy.deviceOwnerAuthentication
_ = (strict, lenient)

评估策略

evaluatePolicy 会执行身份验证,并显示系统的生物识别界面。localizedReason 字符串会向用户说明您请求验证的原因。异步形式会返回一个布尔值,或者抛出错误。

import LocalAuthentication
func authenticate() async -> Bool {
    let context = LAContext()
    do {
        return try await context.evaluatePolicy(
            .deviceOwnerAuthentication,
            localizedReason:
                String(localized: "Unlock your account"))
    } catch {
        return false
    }
}

检测生物识别类型

调用 canEvaluatePolicy 后,context.biometryType 会告知您设备使用的是 .faceID、.touchID、.opticID 还是 .none。您可以据此在自己的界面中显示正确的图标和措辞。

import LocalAuthentication
func biometryLabel() -> String {
    let context = LAContext()
    _ = context.canEvaluatePolicy(
        .deviceOwnerAuthenticationWithBiometrics, error: nil)
    switch context.biometryType {
    case .faceID:  return "Face ID"
    case .touchID: return "Touch ID"
    case .opticID: return "Optic ID"
    default:       return "Passcode"
    }
}

处理错误

失败会以 LAError 代码的形式返回:.userCancel 表示用户取消,.userFallback 表示用户选择了密码,.biometryLockout 表示多次失败后生物识别被锁定,.biometryNotEnrolled 表示尚未录入生物识别信息。请针对这些情况分别处理,为用户提供有帮助的指导,而不是只显示通用的失败提示。

import LocalAuthentication
func describe(_ error: Error) -> String {
    guard let la = error as? LAError else { return "failed" }
    switch la.code {
    case .userCancel:        return "cancelled"
    case .biometryLockout:   return "locked out"
    case .biometryNotEnrolled: return "not set up"
    default:                 return "failed"
    }
}

Face ID 使用说明字符串

要使用面容 ID,必须将 NSFaceIDUsageDescription 添加到 Info.plist,并说明使用原因。如果省略该键,应用在首次评估面容 ID 策略时会崩溃。触控 ID 不需要此键。

// Info.plist:
// NSFaceIDUsageDescription =
//   "We use Face ID to unlock your saved passwords."
let required = "NSFaceIDUsageDescription is mandatory"
_ = required

自定义提示界面

您可以调整提示内容:localizedCancelTitle 会重命名取消按钮,localizedFallbackTitle 会设置回退选项的名称;将其设置为空字符串时则会隐藏该选项。设置空的回退标题可以隐藏密码选项。

import LocalAuthentication
func configured() -> LAContext {
    let context = LAContext()
    context.localizedCancelTitle =
        String(localized: "Not now")
    context.localizedFallbackTitle = "" // hide fallback
    return context
}

重复使用成功的身份验证

默认情况下,每次 evaluatePolicy 都会再次提示用户。设置 touchIDAuthenticationAllowableReuseDuration 后,近期成功的解锁可以满足后续检查,而无需再次显示提示——这对于在短时间内执行一组敏感操作很有用。

import LocalAuthentication
func reusableContext() -> LAContext {
    let context = LAContext()
    context.touchIDAuthenticationAllowableReuseDuration = 30
    return context
}

生物识别与钥匙串访问控制

LAContext 可以验证用户身份,但本身不会保护数据。要实现真正的安全保护,请将它与钥匙串的 SecAccessControl 配合使用,使机密数据在身份验证成功前无法通过密码学方式读取,而不只是将其隐藏在一个经过检查的布尔值后面。

import LocalAuthentication
// A bare evaluatePolicy == true is bypassable if your
// logic is tampered with. Prefer SecAccessControl so
// the data is encrypted until auth succeeds.
let pairing = "combine LAContext with Keychain ACL"
_ = pairing

完整的解锁流程

请将可用性检查、根据类型显示消息、策略评估和错误处理组合到一个健壮的例程中,供用户界面调用。

import LocalAuthentication
func unlock() async -> Bool {
    let context = LAContext()
    var err: NSError?
    guard context.canEvaluatePolicy(
        .deviceOwnerAuthentication, error: &err) else {
        return false
    }
    return (try? await context.evaluatePolicy(
        .deviceOwnerAuthentication,
        localizedReason:
            String(localized: "Access your vault"))) ?? false
}

快速检查

请回忆一下两种主要策略之间的区别。

回顾

您已经学习了生物识别身份验证:

  • 使用 LAContext,并在调用 evaluatePolicy 前先调用 canEvaluatePolicy。
  • .deviceOwnerAuthenticationWithBiometrics 仅使用生物识别;.deviceOwnerAuthentication 会增加密码回退。
  • 读取 biometryType 以使用正确的措辞,并处理 LAError 中的 .biometryLockout 等代码。
  • 添加 NSFaceIDUsageDescription,并与钥匙串的 SecAccessControl 配合使用,以实现真正的保护。

常见问题解答

「生物识别身份验证」课时是免费的吗?

是的 — 「生物识别身份验证」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「生物识别身份验证」这节课中我会学到什么?

使用 Face ID 和 Touch ID 验证用户身份。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「生物识别身份验证」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 在钥匙串中存储机密
  2. 钥匙串访问控制
  3. 生物识别身份验证
  4. 数据保护与加密
← 返回 Swift Academy