【发布时间】:2019-04-18 11:51:10
【问题描述】:
我继承了具有以下类的代码库,该类提供对 Face/Touch ID 的支持。
预期的行为是用户在 Face/Touch 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 { }
我应该指出,在模拟器上这似乎按预期工作,但在设备上却没有,我退出了。
【问题讨论】:
-
您是否尝试过设置断点并检查错误是什么?您至少会确切知道代码的哪一部分正在执行,因为您听起来不能 100% 确定。
-
如果用户没有启用
FaceID/TouchID,那么您应该简单地显示您的默认身份验证流程。在设备上,检查您是否启用了FaceID/TouchID。它适用于模拟器,因为您可以简单地注册和匹配/取消匹配。 -
也许这个对你有帮助请检查并尝试一下stackoverflow.com/a/52093551/10150796
-
policy必须更改为LAPolicy.deviceOwnerAuthentication以便回退到密码验证。
标签: ios swift touch-id face-id localauthentication