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")
}
}