[英]Successfully stored String value to keychain, but always failed to read it out
我正在使用XCode8 + Swift3开发一个iOS项目。
我创建了以下两个函数来将字符串存储到钥匙串中并从钥匙串中读取它:
var query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "my service",
kSecAttrAccount as String: "my-key"
]
func storeString(value: String) -> Bool {
if let data = value.data(using: .utf8) {
// delete data if exist
SecItemDelete(query as CFDictionary)
// add value to query
query[kSecValueData as String] = data
// add to keychain
let status = SecItemAdd(query as CFDictionary, nil)
return status == noErr
}
return false
}
func readString() -> String? {
// update query
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecMatchLimit as String] = kSecMatchLimit
var result: AnyObject?
// fetch items from keychain
let status: OSStatus = withUnsafeMutablePointer(to: &result) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
// I always get error -50 here
if status == noErr {
if let resultData = result as? Data {
if let strVal = String(data: resultData, encoding: .utf8) {
return strVal
}
}
}
return nil
}
我调用这些函数:
boolean hasStored = storeString(value: "John")
let readVal = readString()
我得到hasStored
为true
,但readVal
始终为nil
。 我调查了我的函数,发现在读取器函数中总是收到错误-50作为状态码 (请参见函数中的注释)。
为什么? 为什么我无法读取存储在钥匙串中的值(我不确定它是否确实存储了,但是我确实得到了status == noErr
总是在storeString(value:)
函数中将其设置为true
)
您的代码中有一个错字:
query[kSecMatchLimit as String] = kSecMatchLimit
// ^~~~~~~~~~~~~~
kSecMatchLimit
是密钥,不是有效值。 期望值应为CFNumber
或kSecMatchLimitOne
或kSecMatchLimitAll
。 如果您希望返回单个项目,请使用kSecMatchLimitOne
。 另请参阅搜索属性键和值 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.