我们有一个要求,如果 Face ID 或 Touch ID 连续 5 次失败,我们必须阻止用户 24 小时。
在 Face ID 中,我再次使用回退调用身份验证管理器,总共尝试 6 次(每次调用 2 次)后,我在回退方法本身中阻止了用户。
在 Touch ID 中,在第三次失败时,我收到了对身份验证失败的回调。我再次调用身份验证管理器,在第 5 次尝试时,我收到了对 Lockout 的回调,我可以在其中阻止用户。
Face ID 和 Touch ID 有什么共同点,我可以在每次失败后得到回调,这样我就可以在第 5 次失败时阻止用户?
//MARK:- Check if user has valid biometry, if yes, validate, else, show error
fileprivate func biometricAuthentication(completion: @escaping ((Bool) -> ())){
// addBlurredBackground()
//Check if device have Biometric sensor
if biometryRetryCount == 2 {
authenticationContext.localizedFallbackTitle = "Ok"
} else {
authenticationContext.localizedFallbackTitle = "Retry"
}
let isValidSensor : Bool = authenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
if isValidSensor {
//Device have BiometricSensor
authenticationContext.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: biometryRetryCount == 2 ? "You have been blocked from using the application for next 24 hours. Please come back later" : "Touch / Face ID authentication",
reply: { [unowned self] (success, error) -> Void in
if(success) {
// Touch or Face ID recognized
// self.removeBlurredBackground()
completion(true)
} else {
//If not recognized then
if let error = error {
let msgAndAction = self.errorMessage(errorCode: error._code)
if msgAndAction.0 != "" {
UIApplication.topViewController()?.showAlert(withTitle: "Error", andMessage: msgAndAction.0, andActions: msgAndAction.1)
}
}
completion(false)
}
})
} else {
let msgAndAction = self.errorMessage(errorCode: (error?._code)!)
if msgAndAction.0 != ""{
UIApplication.topViewController()?.showAlert(withTitle: "Error", andMessage: msgAndAction.0, andActions: msgAndAction.1)
}
}
}
错误方法:
//MARK: TouchID error
fileprivate func errorMessage(errorCode:Int) -> (strMessage: String, action: [UIAlertAction]){
var strMessage = ""
let cancelAction = UIAlertAction.init(title: Const.Localize.Common().kCancel, style: .cancel) { (cancelAction) in
}
var actions: [UIAlertAction] = [cancelAction]
switch errorCode {
case LAError.Code.authenticationFailed.rawValue:
biometricAuthentication { (success) in
//
}
case LAError.Code.userCancel.rawValue:
if biometryRetryCount == 2 {
blockUserFor24Hours()
} else {
showAlertOnCancelTapAction()
}
case LAError.Code.passcodeNotSet.rawValue:
strMessage = "Please goto the Settings & Turn On Passcode"
case LAError.Code.userFallback.rawValue:
biometryRetryCount -= 2
if biometryRetryCount == 0 {
blockUserFor24Hours()
} else {
biometricAuthentication { (success) in
//
}
}
default:
strMessage = evaluatePolicyFailErrorMessageForLA(errorCode: errorCode).strMessage
actions = evaluatePolicyFailErrorMessageForLA(errorCode: errorCode).action
}
return (strMessage, actions)
}
func evaluatePolicyFailErrorMessageForLA(errorCode: Int) -> (strMessage: String, action: [UIAlertAction]){
let cancelAction = UIAlertAction.init(title: Const.Localize.Common().kCancel, style: .cancel) { (cancelAction) in
}
var actions: [UIAlertAction] = [cancelAction]
var message = ""
if #available(iOS 11.0, macOS 10.13, *) {
switch errorCode {
case LAError.biometryNotAvailable.rawValue:
message = "Authentication could not start because the device does not support biometric authentication."
case LAError.biometryLockout.rawValue:
showPasscodeScreen()
case LAError.biometryNotEnrolled.rawValue:
message = "You do not have a registered biometric authentication. Kindly go to the settings and setup one"
let settingsAction = UIAlertAction.init(title: Const.Localize.Common().kSetting, style: .default) { (settingsAction) in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}
actions.append(settingsAction)
default:
message = "Did not find error code on LAError object"
}
} else {
switch errorCode {
case LAError.touchIDLockout.rawValue:
showPasscodeScreen()
case LAError.touchIDNotAvailable.rawValue:
message = "TouchID is not available on the device"
case LAError.touchIDNotEnrolled.rawValue:
message = "You do not have a registered biometric authentication. Kindly go to the settings and setup one"
let settingsAction = UIAlertAction.init(title: Const.Localize.Common().kSetting, style: .default) { (settingsAction) in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}
actions.append(settingsAction)
default:
message = "Did not find error code on LAError object"
}
}
return (message, actions)
}