2015-04-09 6 views
5

Ich habe TouchID eingerichtet und funktioniert gut in meiner Anwendung.Einstellen der TouchID "Enter Password" Fallback zum Starten der Bearbeitung UITextField

Ich möchte jedoch die Funktionalität von "Passwort eingeben" ändern.

Wenn meine Authentifizierung Erstellen ich wurde nach dem Tutorial von: http://www.appcoda.com/touch-id-api-ios8/

aber sie Benutzer eine Alertview für die „Passwort eingeben“ Option.

Ich möchte die touchID alertview ablehnen und mein passwordTextField zum erstenResponder machen.

Natürlich habe ich versucht:

self.passwordTextField.becomeFirstResponder() 

Aber das verursacht einen Fehler:

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! 

Hier ist meine Funktion zur Authentifizierung:

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

Es macht auszudrucken

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

Ich weiß, es ruft die richtige .case

Jede Hilfe bekommen es meine UITextField zu wählen wäre sehr dankbar!

+1

haben Sie versucht, den findFirstResponder auf den Hauptthread zu setzen? –

+0

@PaulCezanne Nein, ich habe nicht, wie würdest du das machen? –

+0

@PaulCezanne Ich brauchte eine Weile um herauszufinden. Aber dein Vorschlag hat funktioniert, danke :) –

Antwort

4

Sie müssen den FirstResponder auf den Hauptthread setzen. iOS erfordert, dass alle Benutzeroberflächenvorgänge im Hauptthread ausgeführt werden. Bei Verwendung von Closures (Blöcken in Objective-C) wird die Benutzeroberfläche häufig versehentlich aus dem Hauptthread entfernt. Der übliche Fehler, den Sie bekommen, ist, dass die Benutzeroberfläche für ein paar Sekunden "einfriert". Das ist der klassische Fall, wenn man nicht im Hauptthread ist.

Ihr Fall ist ein wenig anders, aber das Protokoll in der Konsole gab die Antwort: "Ausnahme: Nur auf dem Hauptthread laufen!"

Verwandte Themen