我正在尝试存储一个Integer并使用KeyChain检索它.
这就是我保存它的方式:
func SaveNumberOfImagesTaken()
{
let key = "IMAGE_TAKEN"
var taken = 10
let data = NSKeyedArchiver.archivedDataWithRootObject(taken)
let query : [String:AnyObject] = [
kSecclass as String : kSecclassGenericPassword,kSecAttrAccount as String : key,kSecValueData as String : data
]
let status : Osstatus = SecItemAdd(query as CFDictionaryRef,nil)
}
这是我尝试检索它的方式:
func CheckIfKeyChainValueExitss() -> AnyObject? {
var key = "IMAGE_TAKEN"
let query : [String:AnyObject] = [
kSecclass as String : kSecclassGenericPassword,kSecReturnData as String : kcfBooleanTrue,kSecMatchLimit as String : kSecMatchLimitOne ]
var dataTypeRef :Unmanaged<AnyObject>?
let status: Osstatus = SecItemcopyMatching(query,&dataTypeRef)
if let op = dataTypeRef?.toOpaque() {
let data = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
if let string: AnyObject? = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? AnyObject? {
if key == "IMAGE_TAKEN"
{
return string as! String!
}
else if string == nil
{
return nil
}
}
}
return nil
}
我收到以下错误:
Could not cast value of type ‘__NSCFNumber’ to ‘Nsstring’
我试过玩变量但没有成功.
解决方法
我更新了Eric的Swift 3版本:
class KeyChain {
class func save(key: String,data: Data) -> Osstatus {
let query = [
kSecclass as String : kSecclassGenericPassword as String,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,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 }
}
}
用法示例:
let int: Int = 555
let data = Data(from: int)
let status = KeyChain.save(key: "MyNumber",data: data)
print("status: ",status)
if let receivedData = KeyChain.load(key: "MyNumber") {
let result = receivedData.to(type: Int.self)
print("result: ",result)
}