How to save an Array with Objects to UserDefaults

Viewed 7296

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

2 Answers

You can use a more generic approach, using array with specific type:

(myObject = any custom codable object you like)

(myKey = a string constant key to be able to retrieve/set specific array)

//set
setObject(myArray, forKey: mykey)

//get
let myArray = getObject(forKey: mykey, castTo: Array<myObject>.self)

and generic functions also, for any type:

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
    }
}
Related