Search code examples
arraysswiftnsuserdefaultsnskeyedarchiver

How to save and retrieve class object from NSUserDefaults swift?


I'm trying to save my array to NSUserDefaults. But my Array exist with struct.

struct MyData {
    var Text = String()
    var Number = Int()
}

var Data = [MyData]()

I found this and I tried to do this;

let Data2 = NSKeyedArchiver.archivedDataWithRootObject(Data)

But this gives me this: Cannot invoke 'archivedDataWithRootObject' with an argument list of type '([(TableViewController.MyData)])'

Any advice?


Solution

  • Swift structs are not classes, therefore they don't conform to AnyObject protocol.

    And Syntax for archivedDataWithRootObject is:

    class func archivedDataWithRootObject(rootObject: AnyObject) -> NSData
    

    Which means it only accept AnyObject type object and struct doesn't conform AnyObject protocol so you can not use struct here.

    So just change struct to class and it will work fine.

    UPDATE:

    This way you can store it into NSUserDefaults.

    Tested with playGround

    import UIKit
    
    class Person: NSObject, NSCoding {
        var name: String!
        var age: Int!
        required convenience init(coder decoder: NSCoder) {
            self.init()
            self.name = decoder.decodeObjectForKey("name") as! String
            self.age = decoder.decodeObjectForKey("age") as! Int
        }
        convenience init(name: String, age: Int) {
            self.init()
            self.name = name
            self.age = age
        }
        func encodeWithCoder(coder: NSCoder) {
            if let name = name { coder.encodeObject(name, forKey: "name") }
            if let age = age { coder.encodeObject(age, forKey: "age") }
    
    
        }
    
    }
    
    var newPerson = [Person]()
    newPerson.append(Person(name: "Leo", age: 45))
    newPerson.append(Person(name: "Dharmesh", age: 25))
    let personData = NSKeyedArchiver.archivedDataWithRootObject(newPerson)
    NSUserDefaults().setObject(personData, forKey: "personData")
    
    if let loadedData = NSUserDefaults().dataForKey("personData") {
        loadedData
        if let loadedPerson = NSKeyedUnarchiver.unarchiveObjectWithData(loadedData) as? [Person] {
            loadedPerson[0].name   //"Leo"
            loadedPerson[0].age    //45
        }
    }