ios - FaceID 应该回退到密码,但不会
问题描述
我继承了具有以下类的代码库,为 Face/Touch ID 提供支持。
预期的行为是在面部/触摸 ID 成功时用户已登录。这有效。
但是,如果用户未能通过 Face ID 并选择输入他们的密码,一旦调用完成处理程序,他们就会退出。我相信选择使用密码会触发
else {
self.authState = .unauthenticated
completion(.unauthenticated)
}
如何改为触发密码提示?LAPolicy.deviceOwnerAuthentication
我应该使用并评估它来创建第二个策略吗?
import LocalAuthentication
public enum AuthenticationState {
case unknown
case authenticated
case unauthenticated
public func isAuthenticated() -> Bool {
return self == .authenticated
}
}
public protocol TouchIDAuthenticatorType {
var authState: AuthenticationState { get }
func authenticate(reason: String, completion: @escaping (AuthenticationState) -> Void) -> Void
func removeAuthentication() -> Void
}
public protocol LAContextType: class {
func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool
func evaluatePolicy(_ policy: LAPolicy, localizedReason: String, reply: @escaping (Bool, Error?) -> Void)
}
public class TouchIDAuthenticator: TouchIDAuthenticatorType {
public var authState: AuthenticationState = .unknown
private var context: LAContextType
private var policy = LAPolicy.deviceOwnerAuthenticationWithBiometrics
public init(context: LAContextType = LAContext()) {
self.context = context
}
public func authenticate(reason: String, completion: @escaping (AuthenticationState) -> Void) -> Void {
var error: NSError?
if context.canEvaluatePolicy(policy, error: &error) {
context.evaluatePolicy(policy, localizedReason: reason) { (success, error) in
DispatchQueue.main.async {
if success {
self.authState = .authenticated
completion(.authenticated)
} else {
self.authState = .unauthenticated
completion(.unauthenticated)
}
}
}
} else {
authState = .authenticated
completion(.authenticated)
}
}
public func removeAuthentication() -> Void {
authState = .unknown
context = LAContext() // reset the context
}
}
extension LAContext: LAContextType { }
我应该指出,在模拟器上这似乎按预期工作,但在设备上却没有,我退出了。
解决方案
您必须使用.deviceOwnerAuthentication
而不是要求生物识别。如果 FaceID 可用,它将强制尝试以任何一种方式使用它。
如果您尝试了足够多的时间,那么您将获得另一个“取消”对话框或回退到“使用密码”。选择后备将显示密码屏幕。
但是,如果您指定.deviceOwnerAuthenticationWithBiometrics
,您将获得相同的后备选项。而不是得到这个对话,我会期望收到一个错误LAError.Code.biometryLockout
。但相反,我得到了这个后备选项对话。不过没关系...
但是,如果我随后点击“使用密码”的后备选项,它将不会显示密码警报。相反,它以LAError.Code.userFallback error
.
如果您使用没有生物识别的策略,您将无法获取并且能够捕获 .userFallback 错误。
所以总结一下:
- 如果您要求该
deviceOwnerAuthenticationWithBiometrics
政策,那么您将不得不自己处理回退。 - 如果您
deviceOwnerAuthentication
只要求,则生物识别将在可用和授权的情况下使用,否则如果生物识别不可用,它将自动回退到密码,或者如果生物识别尝试失败,则为您提供自动输入密码的回退选项。
推荐阅读
- javascript - 如何将多个 js 文件中的变量发送到一个 ejs 文件?
- c# - 在 Blazor 中使用 Javascript 互操作获取 URL
- python - 带有变量的Python多行graphql突变-KeyError
- java - 在 PostgraSQL 上选择 FROM OR
- c++ - 如何使用 qml 在 Qt 中创建 Material Design 导航抽屉
- android - Unity3D静态飞溅图像缩放选项不起作用
- spring - FK 在一对多关系中引用的 JPA 组合 PK
- python - 用python display b''登录豆瓣
- jquery - Ans 键出现了,但没有任何计算可以使用
- css - 如何根据天气侧nav在材质Angular中打开或关闭动态设置主要内容的宽度