Hinzufügen von Elementen zum iOS-Schlüsselbund und Abfragen mit Swift

Ich habe Probleme, alle zu konvertierenObjective C Codebeispiele, die zum Hinzufügen von Daten und Abfragen von Daten aus dem verfügbar sindiOS Keychain inSchnell. Ich versuche, eine Zeichenfolge (ein Zugriffstoken) einfach zu speichern und zurückzulesen. Ich habe mir einige der anderen Fragen zu Stack Overflow angesehen, kann sie aber nicht zum Laufen bringen. Ich habe versucht, eine Lösung aus den verschiedenen Quellen zusammenzustellen.

Bearbeiten 1: Ich habe es mit einem einfacheren Setup versucht, weil ich dachte, mein self.defaultKeychainQuery hätte die Dinge durcheinander gebracht. Ich habe den folgenden Code auf die neueste Version aktualisiert.

Bearbeiten 2: Habe es funktioniert. Ich habe den Datenwert nicht richtig zur Speicherabfrage hinzugefügt. Ich musste den String in NSData konvertieren. Ich habe den folgenden Code auf die neueste Arbeitsversion aktualisiert.

Edit 3: Wie Xerxes weiter unten ausführt, funktioniert dieser Code aufgrund einiger Probleme mit Wörterbüchern nicht mit Xcode-Versionen, die höher als Beta 1 sind. Wenn Sie eine Lösung dafür kennen, lassen Sie es mich bitte wissen.

Update: Ich habe daraus eineSchlüsselbundbibliothek in Swift namens Locksmith geschrieben.

sparen

class func save(service: NSString, data: NSString) {
  var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
  // Instantiate a new default keychain query
  var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, dataFromString], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData])

  // Delete any existing items
  SecItemDelete(keychainQuery as CFDictionaryRef)

  // Add the new keychain item
  var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)

  // Check that it worked ok
  println("Saving status code is: \(status)")
}

Belastung

  class func load(service: NSString) -> AnyObject? {
    // Instantiate a new default keychain query
    // Tell the query to return a result
    // Limit our results to one item
    var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, kCFBooleanTrue, kSecMatchLimitOne], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit])



    // I'm not too sure what's happening here...
    var dataTypeRef :Unmanaged<AnyObject>?

    // Search for the keychain items
    let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)


    println("Loading status code is: \(status)")

    // I'm not too sure what's happening here...
    let opaque = dataTypeRef?.toOpaque()

    if let op = opaque? {
      let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
      println("Retrieved the following data from the keychain: \(retrievedData)")
      var str = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
      println("The decoded string is \(str)")
    } else {
      println("Nothing was retrieved from the keychain.")
    }

    return nil
  }

Verwendung (View Controller)

KeychainService.saveToken("sometoken")
KeychainService.loadToken()

welches diese Bequemlichkeitsmethoden verwendet

class func saveToken(token: NSString) {
    self.save("service", data: token)
  }

class func loadToken() {
    var token = self.load("service")
    if let t = token {
      println("The token is: \(t)")
    }
  }

Dies führt zur Ausgabe in der Konsole:

Saving status code is: 0
Loading status code is: 0
Retrieved the following data from the keychain: <736f6d65 746f6b65 6e>
The decoded string is sometoken

Vielen dank für Deine Hilfe. Ich bin mir nicht sicher, was ich mit dataTypeRef machen soll, wenn ich es habe oder wenn es Daten hat, die den obigen Code enthalten.

Antworten auf die Frage(5)

Ihre Antwort auf die Frage