2017-02-11 52 views
0

我正試圖從keychain中檢索我的應用程序的密鑰,以便它可以用於與服務器進行身份驗證。我已經成功儲存在那裏,但無法取回。從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) 
} 

我評論過我遇到的問題。我如何獲得一個正確的指針傳入函數?它想要一個UnsafeMutablePointer<UInt32>?(在那裏我會選擇什麼樣的價值實際上是)

+0

'VAR LEN:UInt32的= 13'然後len'傳遞'&你的函數。 – vacawama

回答

1

通常,當你想通過UnsafeMutablePoiner<T>?(或UnsafeMutablePoiner<T>),聲明T類型(而不是指向T)的一個變量,並把它作爲inout參數(前綴&)。

因此,針對您的問題,您傳遞keyValPtr的方式也是錯誤的。

對於參數passwordLength: UnsafeMutablePointer<UInt32>?,您需要聲明一個類型爲UInt32的變量。 而對於passwordData: UnsafeMutablePointer<UnsafeMutableRawPointer?>?,則需要聲明UnsafeMutableRawPointer?類型的變量。

而且,不幸的是,在許多情況下,這可能不是一個關鍵問題,當您將Swift String直接傳遞給UnsafePointer<Int8>?時,您需要基於UTF-8表示計算長度。

您可能需要編寫這樣的事:

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