2015-04-09 4 views
5

Ho ricevuto touchID e funzionato correttamente nella mia applicazione.Impostazione della fallback "Inserisci password" TouchID per iniziare a modificare UITextField

Tuttavia mi piacerebbe cambiare la funzionalità di "Inserisci password".

Nel creare la mia autenticazione stavo seguendo il tutorial da: http://www.appcoda.com/touch-id-api-ios8/

Tuttavia essi all'utente un alertView per l'opzione "Enter Password".

Desidero chiudere la visualizzazione di avviso touchID e rendere passwordTextField come primoRispettore.

Naturalmente ho provato:

self.passwordTextField.becomeFirstResponder() 

Ma che causa un errore:

2015-04-09 10:48:42.309 Formula Stocks[3933:964941] *** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView<NSTextContainerView> *, NSTextContainer *, NSUInteger)(), /SourceCache/UIFoundation/UIFoundation-371.13/UIFoundation/TextSystem/NSLayoutManager_Private.m:1547 
2015-04-09 10:48:42.312 Formula Stocks[3933:964941] <NSXPCConnection: 0x1701061e0> connection to service named com.apple.CoreAuthentication.daemon: Warning: Exception caught during decoding of received reply to message 'evaluatePolicy:options:reply:', dropping incoming message and calling failure block. 

Exception: Only run on the main thread! 

Ecco la mia funzione per l'autenticazione:

func requestFingerprintAuthentication() { 
    // Get the local authentication context. 
    let context = LAContext() 

    // Declare a NSError variable. 
    var error: NSError? 

    // Set the reason string that will appear on the authentication alert. 
    var reasonString = "Sign In." 

    // Check if the device can evaluate the policy. 
    if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error) { 
     [context .evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in 

      if success { 
       NSOperationQueue.mainQueue().addOperationWithBlock({() -> Void in 
        println("successfull signin with touchID") 
        self.emailTextField.text = emailID as! String 
        self.passwordTextField.text = passwordID as! String 
        self.signIn(self.signInButton) 
       }) 
      } 
      else{ 
       // If authentication failed then show a message to the console with a short description. 
       // In case that the error is a user fallback, then show the password alert view. 
       println(evalPolicyError?.localizedDescription) 

       switch evalPolicyError!.code { 

       case LAError.SystemCancel.rawValue: 
        println("Authentication was cancelled by the system") 

       case LAError.UserCancel.rawValue: 
        println("Authentication was cancelled by the user") 

       case LAError.UserFallback.rawValue: 
        println("User selected to enter custom password") 
        self.passwordTextField.becomeFirstResponder() 

       default: 
        println("Authentication failed") 
        self.passwordTextField.becomeFirstResponder() 
       } 
      } 

     })] 
    } 
    else{ 
     // If the security policy cannot be evaluated then show a short message depending on the error. 
     switch error!.code{ 

     case LAError.TouchIDNotEnrolled.rawValue: 
      println("TouchID is not enrolled") 

     case LAError.PasscodeNotSet.rawValue: 
      println("A passcode has not been set") 

     default: 
      // The LAError.TouchIDNotAvailable case. 
      println("TouchID not available") 
     } 

     // Optionally the error description can be displayed on the console. 
     println(error?.localizedDescription) 

     // Show the custom alert view to allow users to enter the password. 
     //self.showPasswordAlert() 
     self.passwordTextField.becomeFirstResponder() 
    } 
} 

lo fa stampare i

Optional("Fallback authentication mechanism selected.") 
User selected to enter custom password 

quindi so che sta chiamando il corretto .case

Qualsiasi aiuto ottenerlo per selezionare il mio UITextField sarebbe molto apprezzato!

+1

hai provato a inserire il risultato di diventareFirstResponder sul thread principale? –

+0

@PaulCezanne No, non l'ho fatto, come faresti a riguardo? –

+0

@PaulCezanne Ci ho messo un po 'a capire. Ma il tuo suggerimento ha funzionato, grazie :) –

risposta

4

È necessario inserire diventatoFirstResponder sul thread principale. iOS richiede che tutte le operazioni dell'interfaccia utente siano sul thread principale. Spesso si ottiene un'interfaccia utente accidentalmente fuori dal thread principale quando si utilizzano chiusure (blocchi in Objective-C). Il solito bug che si ottiene è che l'interfaccia utente si "congela" per alcuni secondi. Questo è il classico caso di non essere sul filo principale quando è necessario.

Il tuo caso è un po 'diverso, ma il log nella Console ha dato la risposta: "Eccezione: esegui solo il thread principale!"