Reputation: 111
So I want to make a touchid
authentication but if the touchid
does not match there will be an alert to enter the password and try again
I am using XCode 9.0.0
@IBAction func ac(_ sender: Any) {
let context:LAContext=LAContext()
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil){
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "use your touch id", reply: {(wasCorrect,error) in
if wasCorrect {
print("correct")
}else{
print("incorrect")
}
})
}else{
}
}
Upvotes: 5
Views: 3429
Reputation: 2470
this will work, updated for swift 3 and 4
func authenticationWithTouchID() {
let localAuthenticationContext = LAContext()
localAuthenticationContext.localizedFallbackTitle = "Use Passcode"
var authError: NSError?
let reasonString = "To access the secure data"
if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
localAuthenticationContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString) { success, evaluateError in
if success {
//TODO: User authenticated successfully, take appropriate action
} else {
//TODO: User did not authenticate successfully, look at error and take appropriate action
guard let error = evaluateError else {
return
}
let message = self.evaluateAuthenticationPolicyMessageForLA(errorCode: error._code)
let alert = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
} else {
guard let error = authError else {
return
}
let message = self.evaluateAuthenticationPolicyMessageForLA(errorCode: error._code)
let alert = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
and methods to get the error messages
func evaluatePolicyFailErrorMessageForLA(errorCode: Int) -> String {
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:
message = "Authentication could not continue because the user has been locked out of biometric authentication, due to failing authentication too many times."
case LAError.biometryNotEnrolled.rawValue:
message = "Authentication could not start because the user has not enrolled in biometric authentication."
default:
message = "Did not find error code on LAError object"
}
} else {
switch errorCode {
case LAError.touchIDLockout.rawValue:
message = "Too many failed attempts."
case LAError.touchIDNotAvailable.rawValue:
message = "TouchID is not available on the device"
case LAError.touchIDNotEnrolled.rawValue:
message = "TouchID is not enrolled on the device"
default:
message = "Did not find error code on LAError object"
}
}
return message;
}
func evaluateAuthenticationPolicyMessageForLA(errorCode: Int) -> String {
var message = ""
switch errorCode {
case LAError.authenticationFailed.rawValue:
message = "The user failed to provide valid credentials"
case LAError.appCancel.rawValue:
message = "Authentication was cancelled by application"
case LAError.invalidContext.rawValue:
message = "The context is invalid"
case LAError.notInteractive.rawValue:
message = "Not interactive"
case LAError.passcodeNotSet.rawValue:
message = "Passcode is not set on the device"
case LAError.systemCancel.rawValue:
message = "Authentication was cancelled by the system"
case LAError.userCancel.rawValue:
message = "The user did cancel"
case LAError.userFallback.rawValue:
message = "The user chose to use the fallback"
default:
message = evaluatePolicyFailErrorMessageForLA(errorCode: errorCode)
}
return message
}
Upvotes: 1
Reputation: 815
@IBAction func ac(_ sender: Any) {
let context:LAContext=LAContext()
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil){
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "use your touch id", reply: {(wasCorrect,error) in
if wasCorrect {
}else{
let myalert = UIAlertController(title: " Password Title", message: "Message ", preferredStyle: UIAlertControllerStyle.alert)
myalert.addAction(UIAlertAction(title: "Retry", style: .default) { (action:UIAlertAction!) in
print("retry")
})
self.present(myalert, animated: true)
}
})
}else{
// If You Wanna Show Alert
let myalert = UIAlertController(title: "Title", message: "Message ", preferredStyle: UIAlertControllerStyle.alert)
myalert.addAction(UIAlertAction(title: "Retry", style: .default) { (action:UIAlertAction!) in
print("retry")
})
self.present(myalert, animated: true)
}
}
Upvotes: 0
Reputation: 7669
Hope this will help:
func authenticateUser() {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
let reason = "Identify yourself!"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) {
[unowned self] success, authenticationError in
DispatchQueue.main.async {
if success {
self.runSecretCode()
} else {
let ac = UIAlertController(title: "Authentication failed", message: "Sorry!", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
self.present(ac, animated: true)
}
}
}
} else {
let ac = UIAlertController(title: "Touch ID not available", message: "Your device is not configured for Touch ID.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}
For more understanding: https://www.hackingwithswift.com/example-code/system/how-to-use-touch-id-to-authenticate-users-by-fingerprint
Upvotes: 0
Reputation: 10199
The best way (from the users point of view) would be to enable / show a "Re-Authenticate" button if the authentication fails. Then, the user has to actively tap that button to re-run the autentication loop.
If you would automatically start re-authentication instead, the user might get annoyed by autentication dialogs popping up all the time, wich also might look a little weired because sometimes the animations overlap and the screen seems to flicker.
Upvotes: 1