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.
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.
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.
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.
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.
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];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With