Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving a NSMutableArray using NSUserDefaults not working

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.

like image 755
Grauzten Avatar asked May 04 '12 06:05

Grauzten


People also ask

How do I save an array in NSUserDefaults in Objective C?

You can save your mutable array like this: [[NSUserDefaults standardUserDefaults] setObject:yourArray forKey:@"YourKey"]; [[NSUserDefaults standardUserDefaults] synchronize]; Later you get the mutable array back from user defaults. It is important that you get the mutable copy if you want to edit the array later.

What types can you store natively in NSUserDefaults?

Storing Default Objects The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs. These methods are described in Setting Default Values.

What is difference between NSArray and NSMutableArray?

The primary difference between NSArray and NSMutableArray is that a mutable array can be changed/modified after it has been allocated and initialized, whereas an immutable array, NSArray , cannot.

How do you check if NSUserDefaults is empty in Objective C?

There isn't a way to check whether an object within NSUserDefaults is empty or not. However, you can check whether a value for particular key is nil or not.


1 Answers

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];
like image 85
Jonas Schnelli Avatar answered Oct 10 '22 03:10

Jonas Schnelli