2014-09-24 14 views
16

LAContext ha un metodo per verificare se il dispositivo può valutare l'ID touch e fornisce un messaggio di errore. Il problema è che lo stesso messaggio di errore "LAErrorPasscodeNotSet" è dato dal sistema in due casi:iOS8 controlla se il dispositivo ha Touch ID

1) Se l'utente ha Touch ID, ma lo spense nelle impostazioni (iPhone 5s con iOS 8)

2) Se il dispositivo non ha Touch ID (iPad con iOS8)

Q: Come verificare se il dispositivo supporta Touch ID, ma non lo ha acceso nelle impostazioni?

Aggiornamento:

aveva creato biglietto per Apple per quanto riguarda questo bug (ID # 18.364.575) e risposta ricevuta:

"Engineering ha stabilito che questo problema si comporta come previsto sulla base delle seguenti informazioni:

Se la password non è impostato, non sarà in grado di rilevare la presenza touch ID. Una volta che il codice di accesso è impostato, canEvaluatePolicy finirà per tornare LAErrorTouchIDNotAvailable o Los Angeles ErrorTouchIdNotEnrolled e sarete in grado di rilevare la presenza/stato di Touch ID.

Se gli utenti hanno disattivato codice di accesso sul telefono con Touch ID, sapevano che non saranno in grado di utilizzare Touch ID, in modo che le applicazioni non hanno bisogno di rilevare la presenza ID Touch o promuovere la funzionalità basate ID Touch. "

+0

Questa risposta di Engineering ricorda il consiglio per richiedere il permesso di posizione (se l'utente lo ha spento o non autorizzato l'app, quindi non chiedere di nuovo). Il problema è che presume la familiarità con le funzionalità e le impostazioni da parte dell'utente, cioè che saprebbero sempre accenderli nuovamente in Impostazioni. Tuttavia, nella mia esperienza questo è un pio desiderio ... Gli utenti dimenticano queste cose, comprensibilmente. – StephenT

+1

Sembra che Apple abbia risolto questo problema: iOS 8.1 iPad 3 (senza touch) - LAErrorPasscodeNotSet, iOS 8.4 iPad 3 (senza touch) - LAErrorTouchIDNotAvailable – Uladzimir

+0

Solo per curiosità, sul design della tua app: perché ti importa se il dispositivo ha il supporto hardware TouchID , quando l'utente lo ha disabilitato specificamente e non è comunque disponibile per la tua app? –

risposta

7

Forse si potrebbe scrivere un proprio metodo per controllare quali dispositivi sono in esecuzione su, perché se l'errore restituito è lo stesso, sarebbe difficile capire esattamente se tocco ID è supportato. Vorrei andare con qualcosa di simile:

int sysctlbyname(const char *, void *, size_t *, void *, size_t); 

- (NSString *)getSysInfoByName:(char *)typeSpecifier 
{ 
    size_t size; 
    sysctlbyname(typeSpecifier, NULL, &size, NULL, 0); 

    char *answer = malloc(size); 
    sysctlbyname(typeSpecifier, answer, &size, NULL, 0); 

    NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding]; 

    free(answer); 
    return results; 
} 

- (NSString *)modelIdentifier 
{ 
    return [self getSysInfoByName:"hw.machine"]; 
} 

Dopo aver l'identificativo del modello, vorrei solo verificare se identificatore del modello è uguale è uno dei modelli che supportano touch ID:

- (BOOL)hasTouchID 
{ 
    NSArray *touchIDModels = @[ @"iPhone6,1", @"iPhone6,2", @"iPhone7,1", @"iPhone7,2", @"iPad5,3", @"iPad5,4", @"iPad4,7", @"iPad4,8", @"iPad4,9" ]; 

    NSString *model = [self modelIdentifier]; 

    return [touchIDModels containsObject:model]; 
} 

l'array contiene tutti i modelli di ID che supportano Touch ID, che sono:

  • iPhone 5s
  • iPhone 6
  • iPhone 6+
  • iPad Air 2
  • Mini iPad 3

L'unico svantaggio di questo metodo è che una volta rilasciati nuovi dispositivi con Touch ID, l'array del modello dovrà essere aggiornato manualmente.

+1

Grazie, senza legami. Ho suggerito tale soluzione. Ma come hai notato alla fine del messaggio, questa è una soluzione temporanea, quindi dovrei aggiornarla appena possibile quando verrà visualizzato un nuovo dispositivo. Spero ci sia un altro modo, senza aggiornamenti manualmente. – 1ce

+0

Possiamo facilmente presumere che tutti i nuovi iPhone avranno anche Touch ID, quindi potremmo aggiungere qualche logica che se il modello di iPhone è superiore a 6, x potrebbe restituire SÌ. Basta fare attenzione se l'iPad riceve il Touch ID, ma aggiornarlo una volta l'anno non dovrebbe essere un problema, dopotutto - inoltre stai già aggiornando l'app per il nuovo iOS. Basta fare attenzione che non sia dimenticato. – Legoless

+0

Sappiamo che i nuovi dispositivi supporteranno Touch ID in modo che possiamo controllare se il suo iPhone 4S e 5 sappiamo che non supporta Touch ID. Perché iPhone 4 o muggito non può andare a iOS 8 e se il suo errore non iOS8 sarà nullo. In questo modo non è necessario aggiornare l'app se vengono annunciati nuovi dispositivi. – Paragon

1

Integrazione tocco ID

Ora arriviamo alla parte principale del tutorial ... integrando touch ID con l'applicazione. A quanto pare, Apple ha realizzato un codice abbastanza standard per l'accesso a Touch ID.Il codice viene dal quadro Autenticazione locale ed è la seguente:

LAContext *myContext = [[LAContext alloc] init]; 

NSError *authError = nil; 

NSString *myLocalizedReasonString = @"Used for quick and secure access to the test app"; 

if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics 
       localizedReason:myLocalizedReasonString 
         reply:^(BOOL success, NSError *error) { 
      if (success) { 
      // User authenticated successfully, take appropriate action 
      } 
     else { 
      // User did not authenticate successfully, look at error and take appropriate action 
     } 
    }]; 
} 
else { 
// Could not evaluate policy; look at authError and present an appropriate message to user } 

consente di dare uno sguardo a ogni riga per vedere che cosa fa:

Linea 1: Qui creiamo un oggetto LAContext. La classe LAContext è responsabile della gestione del contesto per l'autenticazione. In parole semplici, usiamo un oggetto LAContext per verificare se è disponibile un tipo di autenticazione. Nel caso di questo tutorial, in seguito verificheremo che "se" touch ID è un'opzione.

Riga 2: Abbiamo bisogno di un NSError in modo che LAContext possa utilizzarlo per restituire se c'è un errore.

Riga 3: Impostiamo una NSString con una descrizione che viene visualizzata sullo schermo per consentire all'utente di sapere perché la vista ID touch è stata visualizzata sullo schermo.

Riga 5: qui si inserisce la costante LAContext chiamando il metodo canEvaluatePolicy: e inviando una costante LAPolicy come argomento. In questo caso, passiamo a LAPolicyDeviceOwnerAuthenticationWithBiometrics. In caso di esito negativo, l'ID touch non è configurato su un dispositivo compatibile o l'ID touch non è disponibile sul dispositivo ... pensa un iPhone 4S, 5 o 5c che esegue l'app. Inoltre, questo non tiene conto di un dispositivo con iOS 7, quindi se si prevede di eseguire l'autenticazione con impronta digitale su un'app, assicurarsi di controllare che si stia lavorando con un dispositivo compatibile e, in caso contrario, rendere disponibili altre opzioni come come password sul codice pin per accedere all'app.

Righe 6, 7 e 8: Se l'utente può autenticarsi con dati biometrici, ora è possibile chiamare il metodo evaluatePolicy sul nostro oggetto LAContext. Lo facciamo passando la stessa costante su, LAPolicyDeviceOwnerAuthenticationWithBiometrics, oltre che passando la nostra stringa di motivazione e quindi specificando un blocco per la risposta da gestire.

Come risultato otterremo SÌ o NO. Se sì, allora la riga 10 è dove mettiamo il codice per una risposta positiva. Allo stesso modo, la riga 12 è dove inseriamo il nostro codice di errore.

Finalmente sulla riga 15, abbiamo l'istruzione ELSE che viene eseguita se la riga 5 non supera il test ... vale a dire, la biometria non è disponibile. Possiamo controllare il puntatore authError per ottenere il motivo e presentarlo all'utente se necessario.

Infine, per ottenere questo di non mostrare gli errori, abbiamo bisogno di importare il framework di autenticazione locale al nostro progetto:

Quindi, consente di aggiungere questo codice al nostro progetto. Aprire ViewController.m e in alto, importare il framework di autenticazione locale.

Per maggiori dettagli visitare questo link: http://www.devfright.com/touch-id-tutorial-objective-c/

+0

La tua risposta dovrebbe essere semplice, non come un tutorial completo. –

+0

** Ramraj T, se hai bisogno di ulteriori informazioni sul dispositivo, tocca Touch ID di questo tutorial [collegamento] (http://code.tutsplus.com/tutorials/ios-8-integrating-touch-id--cms-21949) certo ti aiuto ** –

1

In Swift 3

fileprivate func deviceSupportsTouchId(success: @escaping() ->(), failure: @escaping (NSError) ->()) { 
    let context = LAContext() 
    var authError: NSError? 
    let touchIdSetOnDevice = context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authError) 

    if touchIdSetOnDevice { 
     DispatchQueue.main.async { 
      success() 
     } 
    } 
    else { 
     DispatchQueue.main.async { 
      failure(error!) 
     } 
    } 
} 

deviceSupportsTouchId() Successo tornare se il dispositivo è dotato di funzionalità touch id.

In caso contrario, la funzione restituirà un errore, fornendo il seguente codice di errore se touchIDNotEnrolled non è stato ancora impostato.

LAError.Code.touchIDNotEnrolled.rawValue

È possibile gestire utilizzando questo valore.

0

Qui è possibile controllare, touch-ID e Face-ID sia (con iOS 11+)

utilizzare la proprietà biometryType di LAContext per controllare e valutare la politica a disposizione biometrico. (Per un'autenticazione codice di accesso, quando biometrico non riesce, l'uso: LAPolicyDeviceOwnerAuthentication)

Prova questa e vediamo:

Objective-C:

LAContext *laContext = [[LAContext alloc] init]; 

NSError *error; 


// For a passcode authentication , when biometric fails, use: LAPolicyDeviceOwnerAuthentication 
//if ([laContext canEvaluatePolicy: LAPolicyDeviceOwnerAuthentication error:&error]) { 
if ([laContext canEvaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {  
    if (error != NULL) { 
     // handle error 
    } else { 

     if (@available(iOS 11, *)) { 
      if (laContext.biometryType == LABiometryTypeFaceID) { 
       //localizedReason = "Unlock using Face ID" 
       NSLog(@"FaceId support"); 
      } else if (laContext.biometryType == LABiometryTypeTouchID) { 
       //localizedReason = "Unlock using Touch ID" 
       NSLog(@"TouchId support"); 
      } else { 
       //localizedReason = "Unlock using Application Passcode" 
       NSLog(@"No biometric support or Denied biometric support"); 
      } 
     } else { 
      // Fallback on earlier versions 
     } 


     [laContext evaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"Test Reason" reply:^(BOOL success, NSError * _Nullable error) { 

      if (error != NULL) { 
       // handle error 
      } else if (success) { 
       // handle success response 
      } else { 
       // handle false response 
      } 
     }]; 
    } 
} 

Swift:

let laContext = LAContext() 
var error: NSError? 
let biometricsPolicy = LAPolicy.deviceOwnerAuthentication //LAPolicy.deviceOwnerAuthenticationWithBiometrics 

if laContext.isCredentialSet(LACredentialType.applicationPassword) { 
    print("Passsword is set") 
} 

let localizedFallbackTitle = "Unlock Using Device Passcode" 
let localizedCancelTitle = "Use Application Passcode" 
if (laContext.canEvaluatePolicy(biometricsPolicy, error: &error)) { 

    if let laError = error { 
     print("laError - \(laError)") 
     return 
    } 



    //print("biometricsPolicy - \(biometricsPolicy.rawValue)") 

    UINavigationBar.appearance().tintColor = UIColor.red 


    var localizedReason = "My Reason to be displayed on face id prompt" 
    if #available(iOS 11.0, *) { 
     if (laContext.biometryType == LABiometryType.faceID) { 
      //localizedReason = "Unlock using Face ID" 
      print("FaceId support") 
     } else if (laContext.biometryType == LABiometryType.touchID) { 
      //localizedReason = "Unlock using Touch ID" 
      print("TouchId support") 
     } else { 
      //localizedReason = "Unlock using Application Passcode" 
      print("No Biometric support") 
     } 
    } else { 
     // Fallback on earlier versions 
    } 

    laContext.localizedFallbackTitle = localizedFallbackTitle 
    laContext.localizedCancelTitle = localizedCancelTitle 
    //laContext.localizedReason = "test loc reason" 
    laContext.evaluatePolicy(biometricsPolicy, localizedReason: localizedReason, reply: { (isSuccess, error) in 

     DispatchQueue.main.async(execute: { 

      if let laError = error { 
       print("laError - \(laError)") 
      } else { 
       if isSuccess { 
        print("sucess") 
       } else { 
        print("failure") 
       } 
      } 

     }) 
    }) 
} 
Problemi correlati