icekomo icekomo - 1 year ago 591
iOS Question

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

I thought I knew what was causing this error, but I can't seem to figure out what I did wrong.

Here is the full error message I am getting:

Attempt to set a non-property-list object (
"<BC_Person: 0x8f3c140>"
) as an NSUserDefaults value for key personDataArray

I have a
class that I think is conforming to the
protocol, where I have both of these methods in my person class:

- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.personsName forKey:@"BCPersonsName"];
[coder encodeObject:self.personsBills forKey:@"BCPersonsBillsArray"];

- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.personsName = [coder decodeObjectForKey:@"BCPersonsName"];
self.personsBills = [coder decodeObjectForKey:@"BCPersonsBillsArray"];
return self;

At some point in the app, the
in the
is set, and I have a
class that I think is handling the encoding the properties in my
Here is the code I am using from the

- (void)savePersonArrayData:(BC_Person *)personObject
// NSLog(@"name of the person %@", personObject.personsName);

[mutableDataArray addObject:personObject];

// set the temp array to the mutableData array
tempMuteArray = [NSMutableArray arrayWithArray:mutableDataArray];

// save the person object as nsData
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];

// first add the person object to the mutable array
[tempMuteArray addObject:personEncodedObject];

// NSLog(@"Objects in the array %lu", (unsigned long)mutableDataArray.count);

// now we set that data array to the mutable array for saving
dataArray = [[NSArray alloc] initWithArray:mutableDataArray];
//dataArray = [NSArray arrayWithArray:mutableDataArray];

// save the object to NS User Defaults
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:dataArray forKey:@"personDataArray"];
[userData synchronize];

I hope this is enough code to give you an idea o what I am trying to do.
Again I know my problem lie with how I am encoding my properties in my BC_Person class, I just can't seem to figure out what though I'm doing wrong.

Thanks for the help!

Answer Source

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"];
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download