I have an app where the user can authenticate either with TouchID
/ FaceID
(if Available, enrolled and enabled) or with passcode. All those options can be set in the settings of the app and are stored in UserDefaults
. Once the app loads, it checks if those Bool
keys have true value in UserDefaults
and act accordingly.
My problem comes when a user has a device with TouchID/FaceID but they haven't enabled & enrolled it. In this case, the app should show passcode screen only. But instead, I'm presented by TouchID
on my iPhone, when I have disabled the option (for testing purposes). According to Apple's documentation, it says:
If Touch ID or Face ID is available, enrolled, and not disabled, the user is asked for that first. Otherwise, they are asked to enter the device passcode.
On a simulator, I see the Passcode screen, but on my iPhone, I see the TouchID
pop up when it's disabled and UserDefaults
returns false
for that key. Why is that happening? What am I doing wrong?
override func viewDidLoad() {
super.viewDidLoad()
setUI()
}
func setUI() {
let faceTouchIdState = UserDefaults.standard.bool(forKey: DefaultsKeys.faceTouchIdState)
let passcodeState = UserDefaults.standard.bool(forKey: DefaultsKeys.passcodeState)
if faceTouchIdState {
print("Authenticate")
authenticate()
}
else {
print("Passscode")
showEnterPasscode()
}
}
func showEnterPasscode() {
let context = LAContext()
var errMess: NSError?
let policy = LAPolicy.deviceOwnerAuthentication
if context.canEvaluatePolicy(policy, error: &errMess) {
context.evaluatePolicy(policy, localizedReason: "Please authenticate to unlock the app.") { [unowned self] (success, err) in
DispatchQueue.main.async {
if success && err == nil {
self.performSegue(withIdentifier: "GoToTabbar", sender: nil)
}
else {
print(err?.localizedDescription)
}
}
}
}
else {
print("cannot evaluate")
}
}
There is nothing wrong with your code. I believe the issue is on how you did this "I have disabled the option (for testing purposes)".
Since you were prompted with the "Touch ID" pop up, then it proves that your biometric wasn't really disabled. I surmise that you toggled one of the "USE TOUCH ID FOR" switches and thought doing so will disable biometric in your app, which it won't.
If you want to test the fallback to passcode in your device:
OR