Tim*_*m J 6 ios touch-id swift localauthentication face-id
我继承了一个代码库,其中包含以下类,提供对 Face/Touch ID 的支持。
预期的行为是,在 Face/Touch ID 成功后,用户就会登录。这是有效的。
但是,如果用户未能通过 Face ID 并选择输入密码,则一旦调用完成处理程序,他们就会退出。我相信选择使用密码会触发
else {
self.authState = .unauthenticated
completion(.unauthenticated)
}
Run Code Online (Sandbox Code Playgroud)
如何触发密码提示?我应该使用它来创建第二个策略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 { }
Run Code Online (Sandbox Code Playgroud)
我应该指出,在模拟器上这似乎按预期工作,但在设备上却没有,而且我退出了。
Han*_*kke 17
您必须使用.deviceOwnerAuthentication而不是要求生物识别。如果 FaceID 可用,它将强制尝试以任何一种方式使用它。
如果您尝试足够多次,您将看到另一个对话框“取消”或回退到“使用密码”。选择后备将显示密码屏幕。
但是,如果您指定了.deviceOwnerAuthenticationWithBiometrics,您将获得相同的后备选项。我预计会收到一个错误,而不是得到这个对话LAError.Code.biometryLockout。但相反,我得到了这个后备选项对话。但没关系...
但是,如果我随后点击后备选项“使用密码”,它将不会显示密码警报。相反,它会失败并显示LAError.Code.userFallback error.
如果您使用不带生物识别技术的策略,您将无法捕获 .userFallback 错误。
总结一下:
deviceOwnerAuthenticationWithBiometrics政策,那么您将必须自己处理后备问题。deviceOwnerAuthentication,则在可用且授权的情况下将使用生物识别技术,否则,如果生物识别技术不可用,它将自动回退到密码,或者在生物识别尝试失败时为您提供自动输入密码的回退选项。