Swift saving and retrieving custom object from UserDefaults

Swift 4 or later

You can once again save/test your values in a Playground


UserDefaults need to be tested in a real project. Note: No need to force synchronize. If you want to test the coding/decoding in a playground you can save the data to a plist file in the document directory using the keyed archiver. You need also to fix some issues in your class:


class Person: NSObject, NSCoding {
    let name: String
    let age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    required init(coder decoder: NSCoder) {
        self.name = decoder.decodeObject(forKey: "name") as? String ?? ""
        self.age = decoder.decodeInteger(forKey: "age")
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
        coder.encode(age, forKey: "age")
    }
}

Testing:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            // setting a value for a key
            let newPerson = Person(name: "Joe", age: 10)
            var people = [Person]()
            people.append(newPerson)
            let encodedData = try NSKeyedArchiver.archivedData(withRootObject: people, requiringSecureCoding: false)
            UserDefaults.standard.set(encodedData, forKey: "people")
            // retrieving a value for a key
            if let data = UserDefaults.standard.data(forKey: "people"),
                let myPeopleList = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Person] {
                myPeopleList.forEach({print($0.name, $0.age)})  // Joe 10
            }                    
        } catch {
            print(error)
        }
        
    }
}

Leave a Comment