TouchID Authenticated, but dialog is still displayed

I use TouchID to help users log in to my app. Whenever the application starts, the first thing the user sees is the TouchID dialog.

My problem is that if a user launches my application while his finger is already on the home button, the user will authenticate immediately, and only then will the TouchID dialog box be displayed. Then - no matter what I do to decline the dialog (Enter password or Cancel), the gray screen is always above my application, and I have to restart my iPhone to continue working.

How can i solve this?

+4
source share
2 answers

Make sure you only show the Touch ID dialog when the application state is active. If you display it immediately during startup (which means that the application is still technically inactive), then such problems may occur. This is not documented, and I found it the hard way.

For example, to make sure that it starts when the application is active, you can check the current state of the application and either start it immediately, or when we receive an applicationDidBecomeActive notification. The following is an example:

- (void)setup
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidBecomeActive:)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // We need to be in an active state for Touch ID to play nice
    // If we're not, defer the presentation until we are
    if([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
    {
        [self presentTouchID];
    }
    else
    {
        __weak __typeof(self) wSelf = self;
        _onActiveBlock = ^{
            [wSelf presentTouchID];
        };
    }
}

-(void)applicationDidBecomeActive:(NSNotification *)notif
{
    if(_onActiveBlock)
    {
        _onActiveBlock();
        _onActiveBlock = nil;
    }
}

- (void)presentTouchID
{
    _context = [[LAContext alloc] init];
    _context.localizedFallbackTitle = _fallbackTitle;
    [_context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
             localizedReason:_reason
                       reply: ^(BOOL success, NSError *authenticationError)
     {
         // Handle response here
     }];
}
+1
source

This problem occurs when you use Touch ID immediately after starting the application and changing the current controller or viewport in the response block to evaluate Policy: localizedReason: reply :.

(canEvaluatePolicy: :) Touch ID.

Policy: localizedReason: answer: dispatch_after() :

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                    localizedReason:NSLocalizedString(@"Use Touch ID to Unlock", nil)
                              reply:^(BOOL success, NSError *error) {
                                  if (success) {
                                  }else {
                                      if (error.code == kLAErrorUserCancel) {

                                      }
                                  }
                              }];
});

, :

https://github.com/RungeZhai/TouchIDIssue

(godmoney) .

-1

All Articles