我正在尝试从钥匙串中检索我的应用程序的密钥,以便它可以用于对服务器进行身份验证。我已成功将其存储在那里但无法取回它。
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 :(得分: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)")
}
}