Attempt to set a non-property-list object as an NSUserDefaults Attempt to set a non-property-list object as an NSUserDefaults ios ios

Attempt to set a non-property-list object as an NSUserDefaults


The code you posted tries to save an array of custom objects to NSUserDefaults. You can't do that. Implementing the NSCoding methods doesn't help. You can only store things like NSArray, NSDictionary, NSString, NSData, NSNumber, and NSDate in NSUserDefaults.

You need to convert the object to NSData (like you have in some of the code) and store that NSData in NSUserDefaults. You can even store an NSArray of NSData if you need to.

When you read back the array you need to unarchive the NSData to get back your BC_Person objects.

Perhaps you want this:

- (void)savePersonArrayData:(BC_Person *)personObject {    [mutableDataArray addObject:personObject];    NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:mutableDataArray.count];    for (BC_Person *personObject in mutableDataArray) {         NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];        [archiveArray addObject:personEncodedObject];    }    NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];    [userData setObject:archiveArray forKey:@"personDataArray"];}


It seems rather wasteful to me to run through the array and encode the objects into NSData yourself. Your error BC_Person is a non-property-list object is telling you that the framework doesn't know how to serialize your person object.

So all that is needed is to ensure that your person object conforms to NSCoding then you can simply convert your array of custom objects into NSData and store that to defaults. Heres a playground:

Edit: Writing to NSUserDefaults is broken on Xcode 7 so the playground will archive to data and back and print an output. The UserDefaults step is included in case its fixed at a later point

//: Playground - noun: a place where people can playimport Foundationclass Person: NSObject, NSCoding {    let surname: String    let firstname: String    required init(firstname:String, surname:String) {        self.firstname = firstname        self.surname = surname        super.init()    }    //MARK: - NSCoding -    required init(coder aDecoder: NSCoder) {        surname = aDecoder.decodeObjectForKey("surname") as! String        firstname = aDecoder.decodeObjectForKey("firstname") as! String    }    func encodeWithCoder(aCoder: NSCoder) {        aCoder.encodeObject(firstname, forKey: "firstname")        aCoder.encodeObject(surname, forKey: "surname")    }}//: ### Now lets define a function to convert our array to NSDatafunc archivePeople(people:[Person]) -> NSData {    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(people as NSArray)    return archivedObject}//: ### Create some peoplelet people = [Person(firstname: "johnny", surname:"appleseed"),Person(firstname: "peter", surname: "mill")]//: ### Archive our people to NSDatalet peopleData = archivePeople(people)if let unarchivedPeople = NSKeyedUnarchiver.unarchiveObjectWithData(peopleData) as? [Person] {    for person in unarchivedPeople {        print("\(person.firstname), you have been unarchived")    }} else {    print("Failed to unarchive people")}//: ### Lets try use NSUserDefaultslet UserDefaultsPeopleKey = "peoplekey"func savePeople(people:[Person]) {    let archivedObject = archivePeople(people)    let defaults = NSUserDefaults.standardUserDefaults()    defaults.setObject(archivedObject, forKey: UserDefaultsPeopleKey)    defaults.synchronize()}func retrievePeople() -> [Person]? {    if let unarchivedObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsPeopleKey) as? NSData {        return NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject) as? [Person]    }    return nil}if let retrievedPeople = retrievePeople() {    for person in retrievedPeople {        print("\(person.firstname), you have been unarchived")    }} else {    print("Writing to UserDefaults is still broken in playgrounds")}

And Voila, you have stored an array of custom objects into NSUserDefaults


To save:

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];NSData *data = [NSKeyedArchiver archivedDataWithRootObject:yourObject];[currentDefaults setObject:data forKey:@"yourKeyName"];

To Get:

NSData *data = [currentDefaults objectForKey:@"yourKeyName"];yourObjectType * token = [NSKeyedUnarchiver unarchiveObjectWithData:data];

For Remove

[currentDefaults removeObjectForKey:@"yourKeyName"];