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.

Original source

Related problems