我已经实现了一个类,在this answer之后将一些字符串保存到Keychain中。所以代码是
class KeyChain {
class func save(label: String, data: Data) -> OSStatus {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : label,
kSecValueData as String : data ] as [String : Any]
SecItemDelete(query as CFDictionary)
return SecItemAdd(query as CFDictionary, nil)
}
class func load(key: String) -> Data? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : kSecMatchLimitOne ] as [String : Any]
var dataTypeRef: AnyObject? = nil
let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == noErr {
return dataTypeRef as! Data?
} else {
return nil
}
}
class func createUniqueID() -> String {
let uuid: CFUUID = CFUUIDCreate(nil)
let cfStr: CFString = CFUUIDCreateString(nil, uuid)
let swiftString: String = cfStr as String
return swiftString
}
}
extension Data {
init<T>(from value: T) {
var value = value
self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
func to<T>(type: T.Type) -> T {
return self.withUnsafeBytes { $0.pointee }
}
}
使用这种方式检索和保存数据
//Retrieve
var user = String()
if let receivedData = KeyChain.load(key: "KEY") {
user = receivedData.to(type: String.self)
print(user)
} else {
print("Error")
}
//Save
KeyChain.save(label: "KEY", data: dataUser)
存储过程没关系。当我保存一个字符串,任何类型和长度时,我通过检索功能竞争性地打印该字符串,以测试该过程。在这种情况下,检索它没问题。
但是,当我尝试检索数据时,例如,在应用启动时,我在此功能中出错
func to<T>(type: T.Type) -> T {
return self.withUnsafeBytes { $0.pointee }
}
错误是
主题1:EXC_BAD_ACCESS(代码= 1,地址= 0x556a4bec8)
我尝试了很多组合来调试问题:
ci2ao4d OK
cia4o5 OK
Ci4o0 OK
password9pass7 NO OK
pass9pass7 NO OK
luca9luca7 NO OK
luc9luc7 OK
lucas9lucas7 NO OK
lucaselucase NO OK
provaprova NO OK
provaprov OK
123456789 OK
1234567891 NO OK
似乎问题是字符串超过9个字符。但在那之后我尝试了jamesjames
,错误返回。不是alfonsosol
,10个字符。
我在iPhone 6s + 10.2上运行此测试,所以64位。 使用带有iOS 10.3.3的iPhone 5s,32位,结果会发生变化并且更随机。
哪里错了?