Face ID loop/race condition

A Face ID-enabled App can interfere with the swipe up to open gesture and wedge an iPhone X. A short movie is at:


https://www.icloud.com/iclouddrive/0UvDwERD-5SZg1ebBzBagIfmw#FaceIDWedge.mp4


The essential flow is this:


iPhone X unlocks with Face ID, waits at lock screen for swipe up gesture:

  • begin swipe up gesture
  • applicationWillEnterForeground: is called, which invokes evaluatePolicy:localizedReason:reply:
  • for some reason swipe up gesture does not complete and applicationDidEnterBackground: is invoked
  • Face ID succeeds and a new view controller is loaded
  • but we’re back to the iPhone lock screen, waiting for swipe up gesture

Here are the log entries:

2017-11-06 07:38:07.175559-0500 Krypton[4110:1767456] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles


2017-11-06 07:38:07.175803-0500 Krypton[4110:1767456] [MC] Reading from public effective user settings.

2017-11-06 07:38:07.272256-0500 Krypton[4110:1767456] [MC] Lazy loading NSBundle MobileCoreServices.framework

2017-11-06 07:38:07.272774-0500 Krypton[4110:1767456] [MC] Loaded MobileCoreServices.framework

2017-11-06 07:38:07.430678-0500 Krypton[4110:1767456] evaluatePolicy now ...

2017-11-06 07:38:07.433190-0500 Krypton[4110:1767456] refreshPreferences: HangTracerEnabled: 0

2017-11-06 07:38:07.433223-0500 Krypton[4110:1767456] refreshPreferences: HangTracerDuration: 500

2017-11-06 07:38:07.433234-0500 Krypton[4110:1767456] refreshPreferences: ActivationLoggingEnabled: 0 ActivationLoggingTaskedOffByDA:0

2017-11-06 07:38:11.050573-0500 Krypton[4110:1767552] evaluatePolicy Succcess, unlock App


App has started and unlocked itself with Face ID normally. Now lock iPhone with right button.

2017-11-06 07:38:16.995115-0500 Krypton[4110:1767456] didEnterBackground

2017-11-06 07:38:17.030419-0500 Krypton[4110:1767456] evaluatePolicy now ...

2017-11-06 07:38:17.044177-0500 Krypton[4110:1767571] Biometrics failed, code=-1004, err=Error Domain=com.apple.LocalAuthentication Code=-1004 "User interaction is required." UserInfo={NSLocalizedDescription=User interaction is required.}


Movie starts here:

2017-11-06 07:38:25.827161-0500 Krypton[4110:1767456] willEnterForeground

2017-11-06 07:38:25.896164-0500 Krypton[4110:1767456] evaluatePolicy now ...

2017-11-06 07:38:25.971133-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:25.971541-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:26.474765-0500 Krypton[4110:1767456] didEnterBackground

2017-11-06 07:38:28.259041-0500 Krypton[4110:1767935] evaluatePolicy Succcess, unlock App

2017-11-06 07:38:32.448240-0500 Krypton[4110:1767456] willEnterForeground

2017-11-06 07:38:32.479262-0500 Krypton[4110:1767456] evaluatePolicy now ...

2017-11-06 07:38:32.603005-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:32.603285-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:33.119191-0500 Krypton[4110:1767456] didEnterBackground

2017-11-06 07:38:35.230129-0500 Krypton[4110:1767551] evaluatePolicy Succcess, unlock App

2017-11-06 07:38:38.586013-0500 Krypton[4110:1767456] willEnterForeground

2017-11-06 07:38:38.618142-0500 Krypton[4110:1767456] evaluatePolicy now ...

2017-11-06 07:38:38.749139-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:38.749809-0500 Krypton[4110:1767456] +[CATransaction synchronize] called within transaction

2017-11-06 07:38:39.262087-0500 Krypton[4110:1767456] didEnterBackground

2017-11-06 07:38:41.650804-0500 Krypton[4110:1768052] evaluatePolicy Succcess, unlock App


Faced with this I tried two things:

  • Delay invoking evaluatePolicy:localizedReason:reply: for 1 second to give the swipe up transition time to complete, but this is unsatisfying for all the standard reasons.
  • Move the call to evaluatePolicy:localizedReason:reply: from applicationWillEnterForeground: to applicationDidBecomeActive:, which initially showed promise, but now suffers the same fate as before, so there seems to be a timing issue.


At this point I’m a back to using a 1 second delay from the time either applicationWillEnterForeground: or applicationDidBecomeActive: is called before invoking evaluatePolicy:localizedReason:reply: … yuck.


Any other thoughts?

Thanks,

Replies

I am seeing a very similar thing. Calling evaluatePolicy when the app comes to the foreground causes the 'swipe up' gesture to be aborted and the app is put back into the background. The same thing happens whether built for iOS 11 or whether running in legacy mode. I have also reproduced this issue on other developer's apps which use Touch ID/Face ID for access.


Curiously, if you swipe up quickly it works. It is just a fairly slow swipe up which causes it to fail.


Did you make any further progress on this?

Set a flag in applicationWillEnterForeground, then in applicationDidBecomeActive if that flag is true, set it to false and call your authentication code. Without the flag you will end up in loop in applicationDidBecomeActive each time faceId is completed.