Saving a NSMutableArray using NSUserDefaults not working
ios, iphone, nsuserdefaults, xcode
Solution
Your Card class must also conform to the NSCoding Protocol because you can only store `NSData`, `NSString`, `NSArray`, `NSDictionary` and `NSNumber` with `NSUserDefaults`. That means, you need to add two methods to your class:
- (void)encodeWithCoder:(NSCoder *)enCoder {
[super encodeWithCoder:enCoder];
[enCoder encodeObject:instanceVariable forKey:INSTANCEVARIABLE_KEY];
// Similarly for the other instance variables.
....
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
self.instanceVariable = [aDecoder decodeObjectForKey:INSTANCEVARIABLE_KEY];
// similarly for other instance variables
....
}
return self;
}
Then create a NSData NSKeyedArchiver before storing it to NSUserDefaults. Like this:
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSData *yourArrayAsData = [NSKeyedArchiver archivedDataWithRootObject:yourArray];
[ud setObject:sharesAsData forKey:kA_KEY_FOR_USERDEFAULTS];
Problem
I have this mutable array named myWallet with its property declaration: ``` @property (nonatomic, strong) NSMutableArray *myWallet; ``` This array is being filled up by Cards, which is an object. I create a new instance of a Card from another View Controller so I use a delegate method in able to pass this created card on my initial View Controller which is a Table View Controller. Below is the delegate method ``` - (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard { // insert a new card self.myCard = newCard; [self.myWallet addObject:self.myCard]; [self.tableView reloadData]; } ``` So far, I can create new instances of Card, and when I do, a new table cell appears in my initial view controller (Card Wallet VC). What I want is when the user is done using the app, the created instance(s) of Card he / she previously created still appears on next run time of the app. So I used NSUserDefaults to do this. The method below is how I'm using NSUserDefaults to save. ``` - (void)saveMyWallet { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:self.myWallet forKey:@"myWalletArray"]; [defaults synchronize]; NSLog(@"I am saved"); } ``` I call this method inside the didSelectRowAtIndexPath. When I run the app, then create a new instance of a Card, click the table cell, this appears on my log. ``` 2012-05-04 14:51:00.900 CardWallet[24998:f803] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '("<Card: 0x6aa02f0>")' of class '__NSArrayM'. Note that dictionaries and arrays in property lists must also contain only property values. ``` What could be a possible reason to this? And can you suggest me ways I can go about it. Thanks in advance.