2014-10-20 3 views
11

I Die neue touchID-API von ios-8 wurde meiner App hinzugefügt. Es funktioniert normalerweise wie erwartet, ABER beim Eingeben der App, während mein Finger bereits auf Home-Taste ist - API-Erfolg Rückruf wird aufgerufen, aber Pop-up erscheint immer noch auf dem Bildschirm. Nach dem Drücken von CANCEL UI reagiert nicht mehr.Touch-ID, die dazu führt, dass die App nicht mehr reagiert

Antwort

23

begegnete ich auch das gleiche Problem und die Lösung war, den Anruf an die Touch-ID-API unter Verwendung einer Warteschlange mit hoher Priorität sowie eine Verzögerung aufzurufen:

// 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) { 
           ... 
          } 
         }]; 
    } 
}); 

Bei der Prüfung unserer App, fanden wir, eine Verzögerung von 750ms ist optimal, aber Ihre Laufleistung kann variieren.

Update (03/10/2015): Mehrere iOS-Entwickler, wie 1Password zum Beispiel, are reporting, die iOS 8.2 haben endlich dieses Problem behoben.

+3

Arbeitete für mich :) Große Antwort, danke! – HeTzi

+0

Verwenden von iOS 8.2 und haben das gleiche Problem. Sieht aus wie Problem ist noch nicht vollständig behoben. – JOM

+1

@JOM Es scheint für mich auf iOS 8.2 ohne die 750ms Verzögerung zu arbeiten, aber Sie benötigen immer noch die Warteschlange mit hoher Priorität, wenn Sie es aufrufen. – Aviram

1

Diese akzeptierte Antwort behandelt nicht die zugrunde liegende Ursache des Problems: zweimaliges Aufrufen von evaluatePolicy(), das zweite Mal während des ersten Aufrufs. Die aktuelle Lösung funktioniert also nur manchmal mit Glück, da alles zeitlich abhängig ist.

Das Brute-Force, einfache Möglichkeit, das Problem zu umgehen, ist ein einfaches boolesches Flag, das verhindert, dass nachfolgende Aufrufe stattfinden, bis der erste Vorgang abgeschlossen ist.

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

Ich habe gerade Ihre Lösung in unserer App implementiert und es hat nicht funktioniert - wir sind auf das gleiche Problem gestoßen, das bei @HeTzi aufgetreten ist. – Aviram

+1

Versucht, es zu implementieren, hat nicht funktioniert. – gmaliar

+0

Es scheint, das Problem ist nicht innerhalb der 'LAContext' wird zweimal aufgerufen. – gmaliar

6

Während die Verwendung einer Verzögerung möglicherweise das Problem beheben kann, maskiert es die Ursache. Sie müssen sicherstellen, dass das Touch ID-Dialogfeld nur angezeigt wird, wenn der Anwendungsstatus aktiv ist. Wenn Sie es während des Startvorgangs sofort anzeigen (was bedeutet, dass die Anwendung technisch noch in einem inaktiven Zustand ist), können diese Art von Anzeigeproblemen auftreten. Dies ist nicht dokumentiert, und ich fand das auf die harte Tour. Das Bereitstellen einer Verzögerung scheint es zu beheben, weil Ihre Anwendung bis dahin in einem aktiven Zustand ist, aber dies ist nicht garantiert.

Um sicherzustellen, dass es ausgeführt wird, wenn die Anwendung aktiv ist, können Sie den aktuellen Anwendungsstatus überprüfen und entweder sofort ausführen oder wenn wir die applicationDidBecomeActive-Benachrichtigung erhalten. Siehe unten für ein Beispiel:

- (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

Dies ist eine viel bessere Antwort als die akzeptierte, weil diese Lösung keine lästige Verzögerung verursacht. Toller Fang, danke! Aber ich glaube immer noch, dass dieses Problem von Apple in SDK behoben werden sollte, da offensichtlich fast jede App an diesem Problem leidet. –

+0

Ich verwende eine ähnliche Lösung, der Schlüssel war zu überprüfen/warten auf UIApplicationStateActive. Vielen Dank! – JOM

0

Ich habe angefangen, den "Pending UI-Mechanismus bereits eingestellt." Fehler auch erwähnt, so entschied ich mich zu sehen, ob andere Apps betroffen waren. Ich habe sowohl Dropbox als auch Mint für Touch ID eingerichtet. Sicher genug Touch ID funktionierte auch nicht für sie und sie fielen auf Passcodes zurück.

Ich habe mein Telefon neu gestartet und es hat wieder angefangen zu arbeiten, so dass es scheint, dass die Touch ID ausfällt und aufhört zu arbeiten. Ich bin auf iOS 8.2 BTW.

Ich denke, der richtige Weg, um diese Bedingung zu behandeln ist, wie diese Apps tun und Fallback auf Passwort/Passcode.

Verwandte Themen