如何检测用户拒绝LAPolicy.deviceOwnerAuthentication后FaceID已禁用
检测生物识别权限拒绝状态的解决方案
你遇到的canEvaluatePolicy返回值不实时更新的问题,本质是旧的LAContext实例会缓存历史状态,且你没有主动捕获权限拒绝对应的错误码导致。你不需要依赖canEvaluatePolicy的布尔返回值,直接通过evaluatePolicy回调返回的LAError枚举,就能实时判断用户是否拒绝了生物识别权限。
具体实现步骤
- 每次检测权限/发起验证时,新建独立的LAContext实例,不要复用之前创建的实例,避免缓存的旧状态干扰判断。
- 调用
canEvaluatePolicy时主动传入error指针,捕获权限状态错误,不要传nil。
- 调用
- 如果你需要在用户拒绝生物识别后第一时间捕获状态,优先使用
.deviceOwnerAuthenticationWithBiometrics策略发起验证,而不是直接用自动 fallback 密码的.deviceOwnerAuthentication策略。前者在用户拒绝生物识别权限时会直接返回对应错误,不会自动弹出系统密码验证弹窗。
- 如果你需要在用户拒绝生物识别后第一时间捕获状态,优先使用
核心错误码判断
你需要重点关注LAError的以下枚举值:
LAError.Code.userDenied:用户明确拒绝了App的生物识别权限,此时你可以直接弹出提示引导用户到系统设置中开启权限。LAError.Code.userCancel:用户主动取消了本次验证流程,不属于权限拒绝。LAError.Code.userFallback:用户选择了手动输入密码验证,你可以自行扩展密码验证逻辑。
完整代码示例
import LocalAuthentication import UIKit func checkBiometricAuthStatus() { // 每次调用都新建LAContext实例,避免缓存 let context = LAContext() var policyError: NSError? // 先检测生物识别可用性,传入error指针拿具体错误 guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &policyError) else { if let error = policyError as? LAError { switch error.code { case .userDenied: // 命中权限拒绝,弹出引导提示 showOpenPermissionAlert() case .biometryNotAvailable: print("当前设备不支持生物识别") case .biometryNotEnrolled: print("用户未录入任何生物识别信息") default: print("生物识别不可用:\(error.localizedDescription)") } } return } // 发起生物识别验证 context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "验证身份以登录") { success, error in DispatchQueue.main.async { if success { // 验证成功,走后续登录逻辑 print("生物识别验证通过") } else { guard let error = error as? LAError else { return } switch error.code { case .userDenied: showOpenPermissionAlert() case .userFallback: // 用户选择用密码验证,可调用带密码fallback的策略 context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "输入密码验证") { pwdSuccess, pwdError in // 处理密码验证结果 } case .userCancel: print("用户取消了验证") default: print("验证失败:\(error.localizedDescription)") } } } } } // 引导用户开启权限的弹窗 func showOpenPermissionAlert() { let alert = UIAlertController(title: "生物识别权限已关闭", message: "请前往系统设置中开启FaceID权限,方便你快速登录", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "去设置", style: .default, handler: { _ in guard let settingUrl = URL(string: UIApplication.openSettingsURLString) else { return } UIApplication.shared.open(settingUrl) })) alert.addAction(UIAlertAction(title: "取消", style: .cancel)) UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true) }
注意事项
如果你的业务流程必须使用自动 fallback 密码的.deviceOwnerAuthentication策略,也可以在验证失败的回调中捕获userDenied错误,该错误优先级高于密码验证流程,只要用户拒绝了生物识别权限,无论后续密码验证结果如何,都会返回该错误码。
内容的提问来源于stack exchange,提问作者Paul Ancajima
相关产品推荐
相关产品推荐

