My Object conforms to the new Swift 4 Codeable
protocol. How to save an array of these Objects in UserDefaults
?
struct MyObject: Codeable {
var name: String
var something: [String]
}
myObjectsArray = [MyObject]() // filled with objects
UserDefaults.standard.set(myObjectsArray, forKey: "user_filters")
Error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object
Let's take a look at an example. We access the shared defaults object through the standard class property of the UserDefaults class. We then create an array of strings and store the array in the user's defaults database by invoking the set(_:forKey:) method of the UserDefaults database.
To store them in UserDefaults, we need to implement or confirm Codable to the user-defined class or struct. Codable is a typealias of Decodable & Encodable protocols. It adds the functionality of Encoding and Decoding to the class or struct.
UserDefaults can simply save custom object which conforms to Codable protocol. JSONEncoder and JSONDecoder play important roles for handling the data transformation. Nested object must also conform to Codable protocol in order to encode and decode successfully.
Writing or Setting Values To User Defaults You simply invoke the set(_:forKey:) method on the UserDefaults instance. In this example, we set the value of myKey to true by invoking the set(_:forKey:) method on the shared defaults object.
Whew, I got it working:
Here is the Swift 4 Syntax to save an Array
with Codeable
Objects:
My solution is to encode it as a JSON Object and save that:
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")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With