2017-02-11 55 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)") 
    } 
}