如何将包含对象的数组保存到 UserDefaults
How to save an Array with Objects to UserDefaults
我的对象符合新的 Swift 4 Codeable
协议。如何在 UserDefaults
?
中保存这些对象的数组
struct MyObject: Codeable {
var name: String
var something: [String]
}
myObjectsArray = [MyObject]() // filled with objects
UserDefaults.standard.set(myObjectsArray, forKey: "user_filters")
错误
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'Attempt to insert non-property
list object
哇,我成功了:
这里是 Swift 4 保存 Array
和 Codeable
对象的语法:
我的解决方案是将其编码为 JSON 对象并保存:
static var getAllObjects: [MyObject] {
let defaultObject = MyObject(name: "My Object Name")
if let objects = UserDefaults.standard.value(forKey: "user_objects") as? Data {
let decoder = JSONDecoder()
if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [MyObject] {
return objectsDecoded
} else {
return [defaultObject]
}
} else {
return [defaultObject]
}
}
static func saveAllObjects(allObjects: [MyObject]) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(allObjects){
UserDefaults.standard.set(encoded, forKey: "user_objects")
}
}
您可以使用更通用的方法,使用具有特定类型的数组:
(myObject = 您喜欢的任何自定义可编码对象)
(myKey = 一个字符串常量键能够retrieve/set特定的数组)
//set
setObject(myArray, forKey: mykey)
//get
let myArray = getObject(forKey: mykey, castTo: Array<myObject>.self)
还有泛型函数,适用于任何类型:
func setObject<Object>(_ object: Object, forKey: String) where Object: Encodable
{
let encoder = JSONEncoder()
do {
let data = try encoder.encode(object)
set(data, forKey: forKey)
synchronize()
} catch let encodeErr {
print("Failed to encode object:", encodeErr)
}
}
func getObject<Object>(forKey: String, castTo type: Object.Type) -> Object? where Object: Decodable
{
guard let data = data(forKey: forKey) else { return nil }
let decoder = JSONDecoder()
do {
let object = try decoder.decode(type, from: data)
return object
} catch let decodeError{
print("Failed to decode object:" , decodeError)
return nil
}
}
我的对象符合新的 Swift 4 Codeable
协议。如何在 UserDefaults
?
struct MyObject: Codeable {
var name: String
var something: [String]
}
myObjectsArray = [MyObject]() // filled with objects
UserDefaults.standard.set(myObjectsArray, forKey: "user_filters")
错误
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object
哇,我成功了:
这里是 Swift 4 保存 Array
和 Codeable
对象的语法:
我的解决方案是将其编码为 JSON 对象并保存:
static var getAllObjects: [MyObject] {
let defaultObject = MyObject(name: "My Object Name")
if let objects = UserDefaults.standard.value(forKey: "user_objects") as? Data {
let decoder = JSONDecoder()
if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [MyObject] {
return objectsDecoded
} else {
return [defaultObject]
}
} else {
return [defaultObject]
}
}
static func saveAllObjects(allObjects: [MyObject]) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(allObjects){
UserDefaults.standard.set(encoded, forKey: "user_objects")
}
}
您可以使用更通用的方法,使用具有特定类型的数组:
(myObject = 您喜欢的任何自定义可编码对象)
(myKey = 一个字符串常量键能够retrieve/set特定的数组)
//set
setObject(myArray, forKey: mykey)
//get
let myArray = getObject(forKey: mykey, castTo: Array<myObject>.self)
还有泛型函数,适用于任何类型:
func setObject<Object>(_ object: Object, forKey: String) where Object: Encodable
{
let encoder = JSONEncoder()
do {
let data = try encoder.encode(object)
set(data, forKey: forKey)
synchronize()
} catch let encodeErr {
print("Failed to encode object:", encodeErr)
}
}
func getObject<Object>(forKey: String, castTo type: Object.Type) -> Object? where Object: Decodable
{
guard let data = data(forKey: forKey) else { return nil }
let decoder = JSONDecoder()
do {
let object = try decoder.decode(type, from: data)
return object
} catch let decodeError{
print("Failed to decode object:" , decodeError)
return nil
}
}