成功将String值存入keychain,但总是读取失败
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([=10=]))
}
// 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 作为 reader 函数 中的状态代码(请参阅我在函数中的评论)。
为什么?为什么我无法读取存储在钥匙串中的值(我不确定它是否真的存储了但我确实得到 status == noErr
always retuns true
in storeString(value:)
function)
您的代码中有错别字:
query[kSecMatchLimit as String] = kSecMatchLimit
// ^~~~~~~~~~~~~~
kSecMatchLimit
是键,不是有效值。预期值应为 CFNumber
或 kSecMatchLimitOne
或 kSecMatchLimitAll
。如果您希望退回单个项目,请使用 kSecMatchLimitOne
。另见 Search Attribute Keys and Values。
我正在使用 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([=10=]))
}
// 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 作为 reader 函数 中的状态代码(请参阅我在函数中的评论)。
为什么?为什么我无法读取存储在钥匙串中的值(我不确定它是否真的存储了但我确实得到 status == noErr
always retuns true
in storeString(value:)
function)
您的代码中有错别字:
query[kSecMatchLimit as String] = kSecMatchLimit
// ^~~~~~~~~~~~~~
kSecMatchLimit
是键,不是有效值。预期值应为 CFNumber
或 kSecMatchLimitOne
或 kSecMatchLimitAll
。如果您希望退回单个项目,请使用 kSecMatchLimitOne
。另见 Search Attribute Keys and Values。