Search code examples
iosswifttouch-id

TouchID canceling should dismiss the view controller


For my app I need to save one page of it with TouchID. So the user is kinda forced to use TouchID or if the device does not support it, a password. If the user cancels the TouchID authentication, I want to View to disappear and get back to the root view. I already had that working, but somehow it does not work anymore and I really don't know why?! I just copied until the canceled option, the rest is does not matter I guess.

func authenticateUser() {

    let context = LAContext()
    var error: NSError?
    let reasonString = "Authentication is needed to access your App"

    if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error){

        context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success, policyError) -> Void in
            if success {
                print("authentification successful")


                }

            }else{

                switch policyError!.code{
                case LAError.SystemCancel.rawValue:
                    print("Authentification was canceled by the system")
                case LAError.UserCancel.rawValue:
                    print("Authentication was canceled by user")
                    self.navigationController?.dismissViewControllerAnimated(true, completion: nil)
                //Yes I also tried popToRootViewController, still doesn't work    
}

Solution

  • The documentation for the evaluatePolicy call says:

    "Reply block that is executed when policy evaluation finishes. This block is evaluated on a private queue internal to the framework in an unspecified threading context."

    So the problem is that you are trying to call navigation from the wrong thread. You need to make that call on the UI thread. For example:

    dispatch_async(dispatch_get_main_queue()) {
         // Navigation goes here
    }