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 Person
class that I think is conforming to the NSCoding
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 NSString
in the BC_PersonClass
is set, and I have a DataSave
class that I think is handling the encoding the properties in my BC_PersonClass
.
Here is the code I am using from the DataSave
class:
- (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!
To save:
To Get:
For Remove
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 pointAnd Voila, you have stored an array of custom objects into NSUserDefaults
The code you posted tries to save an array of custom objects to
NSUserDefaults
. You can't do that. Implementing theNSCoding
methods doesn't help. You can only store things likeNSArray
,NSDictionary
,NSString
,NSData
,NSNumber
, andNSDate
inNSUserDefaults
.You need to convert the object to
NSData
(like you have in some of the code) and store thatNSData
inNSUserDefaults
. You can even store anNSArray
ofNSData
if you need to.When you read back the array you need to unarchive the
NSData
to get back yourBC_Person
objects.Perhaps you want this:
Swift 3 Solution
Simple utility class
Model Class
How to call
First off, rmaddy's answer (above) is right: implementing
NSCoding
doesn't help. However, you need to implementNSCoding
to useNSKeyedArchiver
and all that, so it's just one more step... converting viaNSData
.Example methods
So you can wrap your
NSCoding
objects in anNSArray
orNSDictionary
or whatever...