2017-02-11 5 views
0

Ich versuche, den geheimen Schlüssel meiner App vom Schlüsselbund abzurufen, damit er zur Authentifizierung mit dem Server verwendet werden kann. Ich habe es erfolgreich dort gespeichert, kann es aber nicht zurückbekommen.Abrufen des Schlüssels von osx keychain

func getClientKey(){ 
    let keyValptr:UnsafeMutablePointer<UnsafeMutableRawPointer?>? 
    let lenPtr:UnsafeMutablePointer<UInt32>? = UInt32(13) //how do i do this? 
    _ = SecKeychainFindGenericPassword(nil, 
     UInt32(serviceName.characters.count), serviceName, 
     UInt32(accountName.characters.count), accountName, 
     lenPtr, keyValptr, nil) 

    print(keyValptr) 
} 

Ich habe die Linie kommentiert Ich habe Probleme mit. Wie erhalte ich einen korrekten Zeiger, um in die Funktion zu gelangen? Sie will ein UnsafeMutablePointer<UInt32>? (wo ich wählen würde, was der Wert tatsächlich ist)

+0

'var len: UInt32 = 13' und dann passieren' & len' an Ihre Funktion. – vacawama

Antwort

1

Im Allgemeinen, wenn Sie passieren UnsafeMutablePoiner<T>? wollen (oder UnsafeMutablePoiner<T>), können Sie eine Variable vom Typ T (kein Zeiger auf T) erklären und geben es als ein Inout-Parameter (Präfix &).

Also, speziell für Ihr Problem, ist Ihre Art der Weitergabe keyValPtr auch falsch. Für den Parameter passwordLength: UnsafeMutablePointer<UInt32>? müssen Sie eine Variable vom Typ UInt32 deklarieren. Und für passwordData: UnsafeMutablePointer<UnsafeMutableRawPointer?>? müssen Sie eine Variable des Typs UnsafeMutableRawPointer? deklarieren.

Und leider in vielen Fällen ist dies möglicherweise kein kritisches Problem, müssen Sie Länge basierend auf UTF-8-Darstellung berechnen, wenn Swift String direkt an UnsafePointer<Int8>? übergeben.

Sie können so etwas schreiben müssen:

func getClientKey() { 
    var keyVal: UnsafeMutableRawPointer? = nil 
    var len: UInt32 = 13 //<- this value is ignored though... 
    let status = SecKeychainFindGenericPassword(
     nil, 
     UInt32(serviceName.utf8.count), serviceName, //### Use `utf8.count` 
     UInt32(accountName.utf8.count), accountName, //### Use `utf8.count` 
     &len,  //### to pass `UnsafeMutablePointer<UInt32>?`, declare a variable of `UInt32`. 
     &keyVal, //### to pass `UnsafeMutablePointer<UnsafeMutableRawPointer?>?`, declare a variable of `UnsafeMutableRawPointer?`. 
     nil 
    ) 

    if status == noErr { 
     let keyData = Data(bytes: keyVal!, count: Int(len)) 
     //### As noted in the API reference of `SecKeychainFindGenericPassword`, 
     // "You should use the SecKeychainItemFreeContent function to free the memory pointed to by this parameter." 
     SecKeychainItemFreeContent(nil, keyVal) 

     print(keyData as NSData) 
     print(String(data: keyData, encoding: .utf8) ?? "?") 
    } else { 
     //You should not silently ignore erros... 
     print("Error: \(status)") 
    } 
} 
Verwandte Themen