2014-10-20 101 views
11

我加了IOS-8的新touchID API來我的應用程序。 它通常按預期工作,但當我的手指已經在主頁按鈕上時進入應用程序 - API的成功回調被調用,但彈出仍然出現在屏幕上。按下CANCEL UI後無法響應。觸摸ID導致應用無響應

回答

23

我也遇到同樣的問題,解決辦法是調用使用高優先級隊列觸摸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) { 
           ... 
          } 
         }]; 
    } 
}); 

當測試我們的應用程序中,我們發現延遲750毫秒是最佳的,但是你的里程可能會有所不同。

更新(03/10/2015):幾個iOS開發人員,比如1Password,例如are reporting,iOS 8.2終於解決了這個問題。而第一次調用正在進行()調用evaluatePolicy兩次,第二次時間:

+3

爲我工作:)偉大的答案,謝謝! – HeTzi 2014-11-04 08:45:30

+0

使用iOS 8.2並且有同樣的問題。看起來問題尚未完全解決。 – JOM 2015-03-25 19:40:24

+1

@JOM它似乎適用於我的iOS 8.2沒有750毫秒延遲,但你仍然需要高優先級隊列,當你調用它。 – Aviram 2015-03-26 07:50:02

1

此接受的答案沒有解決該問題的根本原因。所以目前的解決方案只有運氣纔有效,因爲一切都是依賴於時間的。

蠻力,直白地解決該問題的方法是一個簡單的布爾標誌,以防止情況的發生,直到第一個完成後續調用。

AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 
if (NSClassFromString(@"LAContext") && ! delegate.touchIDInProgress) { 
    delegate.touchIDInProgress = YES; 
    LAContext *localAuthenticationContext = [[LAContext alloc] init]; 
    __autoreleasing NSError *authenticationError; 
    if ([localAuthenticationContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authenticationError]) { 
     [localAuthenticationContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:kTouchIDReason reply:^(BOOL success, NSError *error) { 
      delegate.touchIDInProgress = NO; 
      if (success) { 
       ... 
      } else { 
       ... 
      } 
     }]; 
    } 
+1

我剛剛在我們的應用程序中實現了您的解決方案,並沒有奏效 - 我們遇到了@HeTzi遇到的同樣的問題。 – Aviram 2014-11-10 09:49:08

+1

試圖執行它,沒有工作。 – gmaliar 2014-11-10 09:51:02

+0

看來這個問題不在'LAContext'裏面被調用兩次.. – gmaliar 2014-11-10 09:59:19

6

雖然使用延遲可以解決問題,但它掩蓋了根本原因。您需要確保在應用程序狀態處於活動狀態時僅顯示Touch 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 
    }]; 
} 
+1

這比接受的答案好得多,因爲這個解決方案不會引入任何煩人的延遲。非常棒,謝謝!但我仍然認爲蘋果在SDK中應該解決這個問題,因爲顯然幾乎每個應用都會遇到這個問題。 – 2015-03-05 07:57:36

+0

我使用類似的解決方案,關鍵是檢查/等待UIApplicationStateActive。很多感謝! – JOM 2015-03-25 21:14:37

0

我開始獲得「Pending UI mechanism already already。」。也提到了錯誤,所以我決定看看其他應用程序是否受到影響。我爲Touch ID設置了Dropbox和Mint。果然,Touch ID並沒有爲他們工作,他們正在退回到密碼。

我重新啓動我的手機,並開始工作了,所以它似乎觸摸ID不能錯誤並停止工作。我在iOS 8.2 btw上。

我想正確的方式來處理這種情況就像那些應用程序並回落到密碼/密碼。