Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix NSInternalInconsistencyException in Swift programming

Tags:

ios

swift

I am creating a new app, and I want to put in a hidden folder. Which is accessed by Face ID/Touch ID. I have implemented the code, but when I run the app, and use Face ID. The app crashes with the error 'NSInternalInconsistencyException'

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.

In my Viewcontroller, I have set up the view as:

override func viewDidLoad() {
    super.viewDidLoad()


    let cornerRadius : CGFloat = 10.0
    containerView.layer.cornerRadius = cornerRadius
    tableView.clipsToBounds = true
    tableView.layer.cornerRadius = 10.0


    // 1
    let context = LAContext()
    var error: NSError?

    // 2
    // check if Touch ID is available
    if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
        // 3
        let reason = "Authenticate with Biometrics"
        context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: {(success, error) in
            // 4
            if success {
                self.showAlertController("Biometrics Authentication Succeeded")
            } else {
                self.showAlertController("Biometrics Authentication Failed")
                }
           })
     }
     // 5
     else {
         showAlertController("Biometrics not available")
    }
}

I want Face ID/Touch ID to work as expected and not crash if verified.

like image 874
Concon23b Avatar asked Aug 30 '19 13:08

Concon23b


1 Answers

You are making UI call (Show alert) on background thread and therefore you are getting this issue.

Change the following

if success {
    self.showAlertController("Biometrics Authentication Succeeded")
} else {
    self.showAlertController("Biometrics Authentication Failed")
}

to

DispatchQueue.main.async {
    if success {
        self.showAlertController("Biometrics Authentication Succeeded")
    } else {
        self.showAlertController("Biometrics Authentication Failed")
    }
}

if you gonna update the UI part, remember always use DispatchQueue.main.async to run those tasks. The UI Changes must run in main thread.

How to add FaceID/TouchID using Swift 4

You can also have look at Logging a User into Your App with Face ID or Touch ID - Apple Documentation If you scroll down to Evaluate a Policy Section.

like image 86
chirag90 Avatar answered Nov 18 '22 18:11

chirag90