2016-04-22 9 views
0

Ich habe einen Webservice, der mir einige Daten wie name, login und auth_token zurückgibt. Bisher habe ich in den NSUserDefaults name und login gespeichert. Jetzt möchte ich auch sicher auth_token speichern, also habe ich beschlossen, es in den Schlüsselbund zu legen. Zu diesem Zweck habe ich beschlossen, https://github.com/matthewpalmer/Locksmith dieses Plugin zu verwenden.Warum kann ich das empfangene (durch den Alamofire-Aufruf) Token nicht im Schlüsselbund in meiner Swift-App platzieren?

Bisher sah mein Code wie folgt aus:

Alamofire.request(.POST, "\(serverURL)/authorization", parameters: params) 
    .validate() 
    .response { (request, response, data, error) in 
     if(error != nil){ 
      print("error = \(error)") 
     }else{ 

      let username = json["name"] 
      let login = json["login"] 
      let auth_token = json["auth_token"] 

      let defaults = NSUserDefaults.standardUserDefaults() 

      defaults.setObject(login, forKey: "login") 
      defaults.setObject(username, forKey: "username") 

      defaults.synchronize() 

      let sb = UIStoryboard(name: "Main", bundle: nil) 
      if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController { 
       self.window!.rootViewController = tabBarVC 
      } 

     } 
} 

aber wenn ich diese Zeile hinzugefügt:

try Locksmith.saveData(["auth_token": json["auth_token"]], forUserAccount: "my_auth_token") 

direkt danach:

let defaults = NSUserDefaults.standardUserDefaults() 

dann Fehler Ich erhalte auf Alamofire.request sagen:

Cannot call value of non-function type 'NSHTTPURLResponse?' 

Also meine Frage ist - wie kann ich meine auth_token, die aus dem Webservice im Schlüsselbund kommt speichern?

Antwort

1

Was in Sie laufen ist ein Typenkonflikt, und die bedauerliche Tatsache, dass die AlamoFire Request Klasse hat sowohl eine Funktion response genannt, und eine Eigenschaft namens response (vom Typ NSHTTPURLResponse?, bekannt vorkommen =))

in Ihrem Code sind Sie try Aufruf, der die umschließende Schließung/Funktion erfordert throws markiert werden, oder Sie haben Ihren Code in einem do-catch

Also, was die schnellen Compiler folgern tun, dass die Schließung Sie schreiben wickeln hat throws als Teil von i ts Definition. Dies entspricht offensichtlich nicht der Definition der Schließung, die an die func response übergeben werden sollte, so versucht es die andereresponse es kann die Eigenschaft finden. Dann scheitert es einfach komplett, weil Sie nicht versuchen können, einen optionalen Typ "anzurufen".

Sie sollten einen Do-Catch in Ihrem Verschluss hinzufügen, um die möglichen Fehler zu behandeln, die Schlosser verursachen können.

Bearbeiten: Als Reaktion auf Ihren Kommentar. Sie müssen diesen Aufruf nur in einen do catch umwandeln, um Fehler richtig zu behandeln. Details zum Swifts-Fehlerbehandlungsmodell finden Sie unter https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html.

Wie für welchen Fehler zu fangen, nur einen Blick durch die Locksmith-API, kann es Fehler werfen, die es von der Keychain API erhält. Zum Glück sie die Fehler definiert haben werfen sie hier: https://github.com/matthewpalmer/Locksmith/blob/master/Source/LocksmithError.swift

Als Beispiel dafür, was zu schreiben, es wäre wie diese

Alamofire.request(.POST, "\(serverURL)/authorization", parameters: params) 
    .validate() 
    .response { (request, response, data, error) in 
     if(error != nil){ 
      print("error = \(error)") 
     }else{ 

      let username = json["name"] 
      let login = json["login"] 
      let auth_token = json["auth_token"] 

      let defaults = NSUserDefaults.standardUserDefaults() 
      do { 
       try Locksmith.saveData(["auth_token": json["auth_token"]], forUserAccount: "my_auth_token") 
      } catch { 
       // Handle the error, however you best see fit 
       print("Error trying to save to keychain \(error)") 
      } 

      defaults.setObject(login, forKey: "login") 
      defaults.setObject(username, forKey: "username") 

      defaults.synchronize() 

      let sb = UIStoryboard(name: "Main", bundle: nil) 
      if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController { 
       self.window!.rootViewController = tabBarVC 
      } 

     } 
} 
+0

Hm etwas sein, ich danke Ihnen für eine sehr klare Antwort! Zwei Fragen allerdings - 1) Könnten Sie mir einen kleinen Codeausschnitt zeigen, wie und wo genau könnte ich es ausdrücken? und die zweite Sache - du hast über Fehler geschrieben, die Schlosser vielleicht werfen - ich dachte nur, dass es eine normale Art ist, Daten in einem Schlüsselspeicher zu speichern - was kann hier schiefgehen? : D – user3766930

+0

@ user3766930 Wenn meine aktualisierte Antwort Ihnen geholfen hat, akzeptieren Sie sie bitte als Antwort – bobDevil