问题描述
我真的对此感到困惑。
class MyClass {
let storage = Storage.sharedService
static let sharedInstance = MyClass()
fileprivate init() {
storage.dumpKeychain()
v1 = storage.loadNonimportantValue()
print("V1: \(v1 ?? "nil")")
v2 = storage.loadImportantValue()
print("V2: \(v2 ?? "nil")")
}
}
storage.dumpKeychain()是函数(从互联网获取),可打印我的应用可访问的钥匙串的内容
func dumpKeychain() {
let query: [String: Any] = [
kSecclass as String : kSecclassGenericPassword,kSecReturnData as String : kcfBooleanFalse!,kSecReturnAttributes as String : kcfBooleanTrue!,kSecReturnRef as String : kcfBooleanTrue!,kSecMatchLimit as String: kSecMatchLimitAll
]
var result: AnyObject?
let lastResultCode = withUnsafeMutablePointer(to: &result) {
SecItemcopyMatching(query as CFDictionary,UnsafeMutablePointer($0))
}
var values = [String:String]()
if lastResultCode == noErr {
let array = result as? Array<Dictionary<String,Any>>
for item in array! {
if let key = item[kSecAttrAccount as String] as? String,let value = item[kSecValueData as String] as? Data {
values[key] = String(data: value,encoding:.utf8)
}
}
}
print(values)
}
storage.loadImportantValue()是从给定的kSecAttrAccount(“重要”)加载值的函数
fileprivate func loadImportantValue() -> String? {
var readQuery : [String : Any] = [
kSecclass as String: kSecclassGenericPassword,kSecAttrAccount as String: "Important",kSecReturnData as String: kcfBooleanTrue!
]
var storedData : AnyObject?
_ = SecItemcopyMatching(readQuery as CFDictionary,&storedData);
return String(data: storedData as? Data,encoding: String.Encoding.utf8)
}
我在日志中看到的是dumpKeychain返回:
[...,"Nonimportant": "correct value","Important": "correct value",...]
然后MyClass初始化程序中的行print(value)打印:
V1: "correct value"
V2: "incorrect value"
这两个调用几乎不可能接连发生,从V2的钥匙串中的同一位置返回两个不同的值,同时V1正常吗?
谢谢
解决方法
好的,我发现了问题。 数据确实有两个不同的值。
此类是框架的一部分,该框架在更新后正在执行此操作。因此,该框架的先前版本正在使用另一个框架来管理钥匙串,并且该框架存储的数据具有比我的新版本更多的属性。而且我认为替换数据实际上是在添加具有较少属性的新条目。
因此,最后,在运行旧版代码并使用较新版本进行更新之后,“相同”键上有两个数据条目。