divyenduz
divyenduz

Reputation: 2027

Saving custom class object's array in NSUserDefaults?

I created a custom class to display in a TableView, I read a custom class object's array in TableView. Now, when I close the app I lose my date. I want to save that data permanently. But when I try to do so, I get the following error:

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

My code is:

@implementation CAChallangeListViewController
- (void)loadInitialData{
    self.challangeItems = [[NSUserDefaults standardUserDefaults] objectForKey:@"challanges"];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[NSUserDefaults standardUserDefaults] setObject:self.challangeItems forKey:@"challanges"];
}

Here, the self. Challange items is a NSMutable array which contains objects of type CAChallange which is a custom class with following interface.

@interface CAChallange : NSObject
    @property NSString *itemName;
    @property BOOL *completed;
    @property (readonly) NSDate *creationDate;
@end

Upvotes: 0

Views: 3903

Answers (3)

Paul Hunter
Paul Hunter

Reputation: 4463

You can use NSKeyedArchiver to create an NSData representation of your object. Your class will need to conform to the NSCoding protocol, which can be a bit tedious, but the AutoCoding category can do the work for you. After adding that to your project, you can easily serialize your objects like this:

id customObject = // Your object to persist
NSData *customObjectData = [NSKeyedArchiver archivedDataWithRootObject:customObject];
[[NSUserDefaults standardUserDefaults] setObject:customObjectData forKey:@"PersistenDataKey"];

And deserialize it like this:

NSData *customObjectData = [[NSUserDefaults standardUserDefaults] objectForKey:@"PersistenDataKey"];
id customObject = [NSKeyedUnarchiver unarchiveObjectWithData:customObjectData];

Upvotes: 1

Echelon
Echelon

Reputation: 7922

Your CAChallange object has a pointer to a BOOL which is not a suitable type for a plist:-

 @property BOOL *completed

This is probably causing the error. You cannot store raw pointers in a plist.

Upvotes: 0

Mundi
Mundi

Reputation: 80271

You can easily accomplish what you are doing by converting your object into a standard dictionary (and back when you need to read it).

NSMutableArray *itemsToSave = [NSMutableArray array];
for (CAChallange *ch in myTableItems) {
   [itemsToSave addObject:@{ @"itemName"     : ch.itemName,
                             @"completed"    : @(ch.completed),
                             @"creationDate" : ch.creationDate }];
}

Upvotes: 3

Related Questions