I have the following implementation of LocalAuthentication as described in many places.
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if success {
let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
self.presentViewController(alert, animated: true, completion: nil)
}
if let error = error {
var message :String
switch(error.code) {
case LAError..AuthenticationFailed:
message = "There was a problem verifying your identity."
case LAError..UserCancel:
message = "You pressed cancel."
case LAError..UserFallback:
message = "You pressed password."
default:
message = "Touch ID may not be configured"
}
let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
self.presentViewController(alert, animated: true, completion: nil)
}
})
})
But after I've successfully authenticated with my fingerprint, then evaluatePolicy(, localizedReason:, reply:) returns success without requesting for any fingerprint. I'm actually enabling or disabling TouchID with a UISwitch, so after disabling and re enabling, I'd like to re-authenticate and re enter my fingerprint.
Why is it caching the authentication?
Thanks
LAContext, once evaluated, will return success until it's deallocated. You can manually invalidate it and then the returned error will be LAError.InvalidContext.
If you want to be prompted with a TouchID confirmation every time, you need to create a LAContext every time. This could be achieved
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if success {
let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
self.presentViewController(alert, animated: true, completion: nil)
}
if let error = error {
var message :String
switch(error.code) {
case LAError..AuthenticationFailed:
message = "There was a problem verifying your identity."
case LAError..UserCancel:
message = "You pressed cancel."
case LAError..UserFallback:
message = "You pressed password."
default:
message = "Touch ID may not be configured"
}
let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
self.presentViewController(alert, animated: true, completion: nil)
}
context = LAContext()
})
})
Since ios 9 there is touchIDAuthenticationAllowableReuseDuration
for the context
The duration for which Touch ID authentication reuse is allowable. If the device was successfully authenticated using Touch ID within the specified time interval, then authentication for the receiver succeeds automatically, without prompting the user for Touch ID. The default value is 0, meaning that Touch ID authentication cannot be reused. The maximum allowable duration for Touch ID authentication reuse is specified by the LATouchIDAuthenticationMaximumAllowableReuseDuration constant. You cannot specify a longer duration by setting this property to a value greater than this constant. Availability iOS (9.0 and later), macOS (10.12 and later)
if you set for example to 60
context.touchIDAuthenticationAllowableReuseDuration = 60
It will auto succeed without checking, if the user has successfully passed the touch id checking in the last 60 secs.
So, you can set to the value that suites you. I find it a good very good and it's annoying to ask the user to touch again while he just did it a few seconds ago.(to unlock the screen for example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With