0

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
2

3 Answers 3

3

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 }];
}
Sign up to request clarification or add additional context in comments.

2 Comments

You are looping in an empty array in the example
Good catch thanks. I needed another variable that describes the original data source.
1

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];

Comments

0

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.

1 Comment

I think it is the CAChallange type the compiler objects to. Booleans are possible as NSUserDefaults.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.