触摸ID会导致应用无响应

HeT*_*Tzi 13 ios touch-id ios8

我在我的应用程序中添加了ios-8的新touchID API.它通常按预期工作,但在我的手指已经在主页按钮时输入应用程序 - API的成功回调被调用但弹出窗口仍然出现在屏幕上.按下CANCEL后,UI变得无响应.

Avi*_*ram 23

我也遇到了同样的问题,解决方案是使用高优先级队列调用Touch ID API,以及延迟:

// Touch ID must be called with a high priority queue, otherwise it might fail.
// Also, a dispatch_after is required, otherwise we might receive "Pending UI mechanism already set."
dispatch_queue_t highPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.75 * NSEC_PER_SEC), highPriorityQueue, ^{
  LAContext *context = [[LAContext alloc] init];
  NSError *error = nil;

  // Check if device supports TouchID
  if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
      // TouchID supported, show it to user
      [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
              localizedReason:@"Unlock Using Touch ID"
                        reply:^(BOOL success, NSError *error) {
                            if (success) {
                                // This action has to be on main thread and must be synchronous
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    ...
                                });
                            }
                            else if (error) {
                                ...
                            }
                        }];
  }
});
Run Code Online (Sandbox Code Playgroud)

在测试我们的应用程序时,我们发现延迟750毫秒是最佳的,但您的里程可能会有所不同.

更新(2015年10月3日):一些iOS开发人员,例如1Password,报告说iOS 8.2已经解决了这个问题.

  • 为我工作:)很棒的回答,谢谢! (3认同)

WDU*_*DUK 8

虽然使用延迟可以解决问题,但它掩盖了根本原因.您需要确保在"应用程序状态"处于活动状态时仅显示"触摸ID"对话框.如果在启动过程中立即显示它(意味着应用程序在技术上仍处于非活动状态),则可能会出现这些类型的显示问题.这没有记录,我发现这很难.提供延迟似乎可以解决它,因为那时应用程序处于活动状态,但这不是保证.

要确保它在应用程序处于活动状态时运行,您可以检查当前的应用程序状态,并立即运行它,或者在我们收到applicationDidBecomeActive通知时运行它.请参阅下面的示例:

- (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
     }];
}
Run Code Online (Sandbox Code Playgroud)

  • 这比接受的答案要好得多,因为这个解决方案不会引入任何恼人的延迟.很棒,谢谢!但是我仍然相信这个问题应该由Apple在SDK中解决,因为很明显几乎每个应用都会遇到这个问题. (2认同)