У нас есть требование, при котором мы должны блокировать пользователя на 24 часа, если Face ID или Touch ID не работают в течение 5 раз подряд.
В Face ID я использую запасной вариант для повторного вызова диспетчера аутентификации, и после 6 попыток (по 2 в каждом вызове) я блокирую пользователя в самом резервном методе.
В Touch ID, при третьем сбое, я получаю обратный вызов для проверки подлинности не удалось. Я снова вызываю диспетчер аутентификации, и с 5-й попытки я получаю обратный вызов в Lockout, в котором я могу заблокировать пользователя.
Есть ли какой-либо способ, как в Face Face, так и в 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)
}