【问题标题】:FaceID should fallback to Passcode but does notFaceID 应该回退到密码,但不会
【发布时间】: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


【解决方案1】:

您必须使用.deviceOwnerAuthentication 而不是要求提供生物识别信息。如果 FaceID 可用,它将强制尝试以任何一种方式使用它。

如果您尝试了足够多的时间,您将获得另一个“取消”对话框或回退到“使用密码”。 选择后备将显示密码屏幕。

但是,如果您指定了.deviceOwnerAuthenticationWithBiometrics,您将获得相同的后备选项。而不是得到这个对话,我本来希望收到LAError.Code.biometryLockout 的错误。但相反,我得到了这个后备选项对话。不过没关系……

但是,如果我随后点击“使用密码”的后备选项,它不会显示密码警报。相反,它以LAError.Code.userFallback error 失败。

如果您使用没有生物识别的策略,您将无法获取并且能够捕获 .userFallback 错误。

总结一下:

  1. 如果您要求使用 deviceOwnerAuthenticationWithBiometrics 政策,那么您必须自己处理回退。
  2. 如果您只要求deviceOwnerAuthentication,则将使用生物识别技术(如果可用并获得授权),否则如果生物识别技术不可用,它将自动回退到密码,或者如果生物识别尝试失败,则为您提供自动输入密码的回退选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多