5

I am developing an application that uses the Face/Touch ID at the opening. I achieved this by adding this func to my MainViewController():

let context = LAContext()

    if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: nil) {
        context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "Verifying") { (success, err) in
            if success {
                DispatchQueue.main.async {
                    self.loginSuccessfull()
                    self.button.removeFromSuperview()
                }
            } else {
                if let err = err {
                    print(err)
                }
            }
        }
    }

This gets called both in the ViewDidLoad and by a button, as shown in this video.

As you can see tho, when I try to close my App it has a very weird behavior, and I am sure that it is caused by the FaceID.

Any suggestion to fix this?

Crash log:

Error Domain=com.apple.LocalAuthentication Code=-4 "Caller moved to background." UserInfo={NSLocalizedDescription=Caller moved to background.}
Vipera74
  • 227
  • 3
  • 17
  • 1
    Can you describe what the weird part is -- I don't see it. – Lou Franco Dec 24 '19 at 19:16
  • @LouFranco at the end, when I close the app, the phone crashes and goes to the home screen – Vipera74 Dec 24 '19 at 20:38
  • Do you get a crash log you can share? – koen Dec 24 '19 at 21:12
  • @koen `2019-12-24 22:27:06.660868+0100 DemoApp[3266:786877] Can't end BackgroundTask: no background task exists with identifier 13 (0xd), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug. Error Domain=com.apple.LocalAuthentication Code=-4 "Caller moved to background." UserInfo={NSLocalizedDescription=Caller moved to background.} ` – Vipera74 Dec 24 '19 at 21:27
  • Maybe this will help: https://stackoverflow.com/questions/23882495/cant-endbackgroundtask-no-background-task-exists-with-identifier-or-it-may-ha – koen Dec 24 '19 at 21:32
  • @koen the actual error is the following (I just debugged it a little more): `Error Domain=com.apple.LocalAuthentication Code=-4 "Caller moved to background." UserInfo={NSLocalizedDescription=Caller moved to background.}` – Vipera74 Dec 24 '19 at 21:35
  • 1
    I'm facing the same issue!, in my case the replay closure is called 2 times, one is in normal flow. the second time after force quit. I wonder why is that?? – Gal Yedidovich Feb 18 '20 at 14:44
  • 1
    Do you have any code in AppDelegate `applicationDidResignActive` or `applicationDidEnterBackground`? – Alexander Feb 18 '20 at 16:13
  • @Alexander in my SceneDelegate the `sceneDidResignActive` is empty and my `sceneDidEnterBackground` only has the `(UIApplication.shared.delegate as? AppDelegate)?.saveContext()` line (already there as the app is using CoreData) – Vipera74 Feb 18 '20 at 17:38

1 Answers1

3

I believe I have found a solution for the issue, by delaying the evaluation.

I noticed that when I have any kind of delay in UI before evaluation (for example: animation that move the logo up before showing the face ID alert) the crash stops altogether.

So I did another test with delay like so:

override func viewDidAppear(_ animated: Bool) {
    let context = LAContext()
    if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Biometric test") { success, error in
                DispatchQueue.main.async {
                    if success {
                        doSome()
                    } else {
                        if let error = error { print(error) }
                    }
                }
            }
        }
    }
}

With that implementation I had zero crashes.

*Note: I also tried different delay times, from 0.1 to 2.0 seconds, all worked for me.

Gal Yedidovich
  • 757
  • 7
  • 16