How to use NSUserDefaults to store an array of custom classes in Swift?

11,575

Solution 1

Your Person class should look like this:

Swift 3:

class Person : NSObject, NSCoding{

    // Person dictionary variable
    var name: String?
    var age: String?
    var html_url: String?

    init(json: NSDictionary) { // Dictionary object
        self.name = json["name"] as? String
        self.age = json["age"] as? String
        self.html_url = json["html_url"] as? String // Location of the JSON file
    }

    required init?(coder aDecoder: NSCoder) {

        self.name = aDecoder.decodeObjectForKey("name") as? String;
        self.age = aDecoder.decodeObjectForKey("age") as? String;
        self.html_url = aDecoder.decodeObjectForKey("html") as? String;
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.name, forKey: "name");
        aCoder.encodeObject(self.age, forKey: "age");
        aCoder.encodeObject(self.html_url, forKey: "html");
    }
}

And here you have an example of saving and retrieving the array from NSUserDefaults:

let p = Person()
p.name = "person1"
p.age = "12"
p.html_url = "www.google.ro"

let p2 = Person()
p2.name = "person2"
p2.age = "11"
p2.html_url = "www.google.ro"

let array = [p, p2]

let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(NSKeyedArchiver.archivedDataWithRootObject(array), forKey: "persons")
userDefaults.synchronize()

let array : [Person]
array = NSKeyedUnarchiver.unarchiveObjectWithData(userDefaults.objectForKey("persons") as! NSData) as! [Person]
print("\(array[0].name)\(array[1].name)")

Swift 4:

class Person : NSObject, NSCoding{

    // Person dictionary variable
    var name: String?
    var age: String?
    var html_url: String?

    init(json: NSDictionary) { // Dictionary object
        self.name = json["name"] as? String
        self.age = json["age"] as? String
        self.html_url = json["html_url"] as? String // Location of the JSON file
    }

    required init?(coder aDecoder: NSCoder) {
        self.name = aDecoder.decodeObject(forKey: "name") as? String;
        self.age = aDecoder.decodeObject(forKey: "age") as? String;
        self.html_url = aDecoder.decodeObject(forKey: "html") as? String;
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.name, forKey: "name");
        aCoder.encode(self.age, forKey: "age");
        aCoder.encode(self.html_url, forKey: "html");
    }
}

Solution 2

You need to implement NSCoding protocol to store custom object into NSUserDefaults. Check out this example http://nshipster.com/nscoding/

Solution 3

Swift 4

  • Confirm codable protocol to your class
  • Serialize(Data) your object using JsonEncoder class
  • Now save your data to userDefaults

See this answer to get clear idea Save Array of Custom Swift object to userDefaults

Share:
11,575
Daniel Bramhall
Author by

Daniel Bramhall

Designer and developer based in rainy Liverpool.

Updated on July 28, 2022

Comments

  • Daniel Bramhall
    Daniel Bramhall almost 2 years

    I have a custom class called Person that stores various attributes about someone when they enter information.

    class Person {
    
        // Person dictionary variable
        var name: String?
        var age: String?
        var html_url: String?
    
        init(json: NSDictionary) { // Dictionary object
            self.name = json["name"] as? String
            self.age = json["age"] as? String
            self.html_url = json["html_url"] as? String // Location of the JSON file
        }
    }
    

    Once the dictionary is created, it is then placed into an array. I am having problems saving the array into NSUserDefaults when a button is tapped.

    personArray.append(newPerson) // newPerson = dictionary of attributes
    
    
    NSUserDefaults.standardUserDefaults().setObject(personArray, forKey: "personArray")
            NSUserDefaults.standardUserDefaults().synchronize()
    

    I have had a look at How to store custom objects in NSUserDefaults and Saving custom SWIFT class with NSCoding to UserDefaults but I have had no luck and am finding it hard to understand.

    I when I simply try to save into NSUserDefaults, I am told the following:

    Attempt to set a non-property-list object (
        "PersonApp.Person"
    ) as an NSUserDefaults/CFPreferences value for key personArray
    

    Would anyone be able to help me actually save an array of custom objects (custom dictionaries) via NSUserDefaults?