Is there a way to detect if the user has declined biometrics (faceID) after using "LAContext().evaluatePolicy(.deviceOwnerAuthentication, localizedReason: someReason)"?
For example,
It appears canEvaluatePolicy returns true for "LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)" until I close and reopen the app.
I want to be able to alert the user that they can turn faceID on in their app settings.
There does not appear to be a way to determine the case you describe in your question.
I note that the documentation for canEvaluatePolicy
states:
Don’t store the return value from this method because it might change as a result of changes in the system. For example, a user might disable Touch ID after you call this method. However, the reported value does remain consistent until your app enters the background.
However, in testing it seems that even putting the app into the background does not change the value returned by canEvaluatePolicy
.
As you note in your question, the value returned does not change until the app is relaunched. You will also see that if you go into preferences and toggle the biometric setting for your app then your app is actually relaunched. This same process happens for other privacy-related settings as well.
You can offer biometric authentication on subsequent launches if you determine that it has been denied, but you should be wary about bugging the user when they have already made a decision.
The other approach you can use is to try LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "reason")
and if that fails due to biometrics being denied, retry the authentication with LAContext().evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "reason")
which will immediately prompt for a passcode.