Ultimately, what I want to have is one function (or probably a function within a separate class) that prompts the user to authenticate via TouchID, then passcode and if either of these are successful then returns a true boolean.
I've figured out the authentication mostly however I can't get the function to return a boolean, here's roughly what I have so far:
The authenticate user function:
func authenticateUser() -> Bool {
let context = LAContext()
var error: NSError?
let reasonString = "Authentication is needed to access your places."
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error) {
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success, policyError) -> Void in
if success {
print("touchID authentication succesful")
} else {
switch policyError!.code {
case LAError.UserFallback.rawValue:
print("User selected to enter password.")
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
default:
print("Authentication failed! :(")
}
}
})
} else {
print(error?.localizedDescription)
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
}
return true
}
It's just set to return true for now for testing purposes. However I'd like to have it return true whenever there's a successful authentication. I can't place the return within the context.evaluatePolicy
because it's inside the block method. Is there another way to do what I want? Or am I going about this in totally the wrong manner?
Also, for reference here is my showPasswordAlert
function:
func showPasswordAlert() {
let alertController = UIAlertController(title: "Passcode", message: "Please enter your passcode.", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default) { (action) -> Void in
if let textField = alertController.textFields?.first as UITextField? {
if let passcode = self.keychainWrapper.myObjectForKey("v_Data") as? String {
if textField.text == passcode {
print("Authentication successful! :) ")
} else {
}
}
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
alertController.addAction(defaultAction)
alertController.addAction(cancelAction)
alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
textField.placeholder = "Enter passcode..."
textField.textAlignment = NSTextAlignment.Center
textField.secureTextEntry = true
textField.keyboardType = UIKeyboardType.NumberPad
}
self.presentViewController(alertController, animated: true, completion: nil)
}
So in my head what I'm thinking is: showPasswordAlert
could also return a true boolean to authenticateUser
and then this would in turn return a true boolean to where the authenticateUser
function is being called. I know there's a simpler way to do that but I'd just like to get it working for now.