Objective C - UserDefaults Over Writing - iphone

I can't seem to re edit this object in my ios User Defaults. Here is my code...
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:nil forKey:#"savedScoreCards2"];
Before I did this I set the key savedScoreCards to a huge 3-d dictionary, and now when I try to over write it or even set the key to nil that huge 3-d dictionary that I set up a while ago is still there. I can't seem to over write/ replace it will nothing (nil), or another huge 3-d dictionary. Any ideas?
UPDATE:
+ (void)saveCurrentScoreCard
{
//save score card
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *savedScoreCards = [[NSMutableDictionary alloc] init];
[userDefaults setObject:nil forKey:#"savedScoreCards2"];//reset at beginning
NSMutableArray *golferOneScoresu = [userDefaults arrayForKey:#"golferOneScoresArray"];
NSMutableArray *golferTwoScoresu = [userDefaults arrayForKey:#"golferTwoScoresArray"];
NSMutableDictionary *golferIconsu = [userDefaults objectForKey:#"golferIconsFirstScene"];
NSMutableArray *golferThreeScoresu = [userDefaults arrayForKey:#"golferThreeScoresArray"];
NSMutableArray *golferFourScoresu = [userDefaults arrayForKey:#"golferFourScoresArray"];
NSMutableDictionary *golferIcons2u = [userDefaults objectForKey:#"golferIcons"];
NSMutableArray *golferNamesu = [userDefaults objectForKey:#"golferNames"];
NSMutableArray *golferNames = [[NSMutableArray alloc] initWithArray:golferNamesu copyItems:YES];
NSMutableDictionary *golferIconsSceneOne = [[NSMutableDictionary alloc]initWithDictionary:golferIconsu];
NSMutableDictionary *golferIcons = [[NSMutableDictionary alloc]initWithDictionary:golferIcons2u];
NSMutableArray *golferFourScores = [[NSMutableArray alloc] initWithArray:golferFourScoresu copyItems:YES];
NSMutableArray *golferThreeScores = [[NSMutableArray alloc] initWithArray:golferThreeScoresu copyItems:YES];
NSMutableArray *golferOneScores = [[NSMutableArray alloc] initWithArray:golferOneScoresu copyItems:YES];
NSMutableArray *golferTwoScores = [[NSMutableArray alloc] initWithArray:golferTwoScoresu copyItems:YES];
NSMutableDictionary *currentScoreCard = [[NSMutableDictionary alloc] init];
[currentScoreCard setObject:golferNames forKey:#"golferNames"];
[currentScoreCard setObject:golferIconsSceneOne forKey:#"golferIconsFirstScene"];
[currentScoreCard setObject:golferIcons forKey:#"golferIcons"];
[currentScoreCard setObject:golferOneScores forKey:#"golferOneScoresArray"];
[currentScoreCard setObject:golferTwoScores forKey:#"golferTwoScoresArray"];
[currentScoreCard setObject:golferThreeScores forKey:#"golferThreeScoresArray"];
[currentScoreCard setObject:golferFourScores forKey:#"golferFourScoresArray"];
[savedScoreCards setObject:currentScoreCard forKey:#"1"];
NSLog([golferIconsSceneOne objectForKey:#"30101"]);
[userDefaults setObject:savedScoreCards forKey:#"savedScoreCards2"];
[userDefaults synchronize];
NSLog(#"SAVED SCORE CARD");
}

Use [userDefaults removeObjectForKey:#"savedScoreCards2"] if you're just trying to remove a stored value.
Also call [userDefaults synchronize]; to "flush" your changes immediately. I think the [userDefaults synchronize] is probably what you're missing.

NSUserDefaults do not save automatically when you make a change to them. Try adding this line below the ones you've posted above:
[userDefaults synchronize];
This should save any changes you've made.
As a side note, I'm not sure you can save 'nil' into NSUserDefaults; at its core I believe it's a dictionary, in which nil values cannot be set. So you might try setting an empty object, instead.
Hope this helps, let me know if you need any more information!

Related

Unable to retrieve NSMutableArray from NSUserDefaults

I have an issue persisting data in local storage for an NSMutableArray containing a list of NSStrings.
I have a save method and a get method both appear to work when the app is running. However, once I close the app and restart the items in the array are gone.
NSMutableArray*ImageTags;
Get Data
-(NSMutableArray*)GetDataNSMutableArray:(NSString*)ItemName
{
NSMutableArray *GetData = [[NSMutableArray alloc] init];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:ItemName];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
GetData = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
GetData = [[NSMutableArray alloc] init];
}
return GetData;
}
Save Data
-(void)SaveDataNSMutableArray:(NSString*)ItemName:(NSMutableArray*)Data
{
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:Data] forKey:ItemName];
}
How items are added
[ImageTags addObject:Control.titleLabel.text]
How array is saved
[super SaveDataNSMutableArray:CVC_ImageURL:ImageTags];
How array is retrieved
ImageTags = [super GetDataNSMutableArray:CVC_ImageURL];
NSUserDefaults always return immutable instances.
Unrelated:
(Conventions says that methodNames should always begin with a small letter).
[[NSUserDefaults standardUserDefaults] synchronize]
To dump all the contents from NSUserDefaults onto persistent store
Your can not store mutable array to user defaults. Store the immutable copy and retrieve that and convert to mutable ones to access during the next launch.
You can do synchronization while saving:
-(void)SaveDataNSMutableArray:(NSString*)ItemName:(NSMutableArray*)Data
{
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:Data] forKey:ItemName];
[[NSUserDefaults standardUserDefaults] synchronize] //add this code of a line.
}

Can we update the array stored in NSUserDefault

I am having values stored in an array, and stored that array in NSUserDefault, then i need to update that array can i do so. If then how?
First retrieve the current data.
NSArray *tempNew = [[NSArray alloc]init];
tempNew = [storeData objectForKey:#"accounts"];
[tempArr addObjectsFromArray:tempNew];
Update:
[tempArr addObject:str];
[storeData setObject:tempArr forKey:#"accounts"];
NSUserDefaults is just as an NSDictionary, so you can use the same method of updating a dictionary by setting another object to the key value -setObject:forKey:.
for example when you try below code
NSUserDefaults *usr=[NSUserDefaults standardUserDefaults];
NSArray *arr= [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2], nil];
[usr setObject:arr forKey:#"num"];
NSLog(#"usr %#",[usr arrayForKey:#"num"]);
NSUserDefaults *usr1=[NSUserDefaults standardUserDefaults];
NSArray *arr= [NSArray arrayWithObjects:[NSNumber numberWithInt:2],[NSNumber
numberWithInt:3], nil];
[usr setObject:arr forKey:#"num"];
NSLog(#"user1 %#",[usr1 arrayForKey:#"num"]);
u will get
usr (
1,
2
)
usr1 (
2,
3
)
in console.
Just re-store the array in the user defaults and call synchronize.
So for example:
Store your array...
NSMutableArray *yourArray = .... // whatever you did to create your data
// store your data in the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:yourArray forKey:#"myArray"];
[defaults synchronize];
... and then some other time somewhere in your app update it!
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// retrieve your data from the NSUserDefaults
NSMutableArray *yourArray = [defaults objectForKey:#"myArray"];
// edit the data, for example add some object.
[yourArray addObject:someNewObject];
// update the defaults
[defaults setObject:yourArray forKey:#"myArray"];
[defaults synchronize];

Array within a NSDictionary: how to save to the NSUserDefaults

I would like to save Array/NSDictionary to NSUserDefaults but anything I try is just not working. Here is my code so please if you know how to do this, help me.
NSArray *oneArray = [NSArray arrayWithObjects:#"Radio One",nil];
NSDictionary *one = [NSDictionary dictionaryWithObject:oneArray forKey:#"Stations"];
NSArray *oneLinkArray = [NSArray arrayWithObjects:#"http://mobile.com:28000/",nil];
NSDictionary *oneLink = [NSDictionary dictionaryWithObject:oneLinkArray forKey:#"Stations"];
[data addObject:one];
[link addObject:oneLink];
The reason I need this is to put this station into favorites. So my thinking is to save these info in to NSUserDefaults and retrieve in favorites table.
Thanks and please any suggestion is welcomed and appreciated.
You can use something like this when you store everything into a dictionary
[[NSUserDefaults standardUserDefaults] setObject:link forKey:#"dictionary1"];
Or you can put everything into an array and store it like this
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"array1"];
You can access it again by using
NSDictionary * myDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:#"dictionary1"];
Typically adding an object into NSUserDefaults goes like this:
NSMutableDictionary *dictionaryToAdd = [[NSMutableDictionary alloc] init];
[dictionaryToAdd setObject:#"xyz" forKey:#"myKey"];
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[myDefaults setObject:dictionaryToAdd forKey:#"someKey"];
[myDefaults synchronize];
A few things on your code above though - you're adding stuff into 'data' and 'link' but I don't see those in your code, so I'm assuming those arrays exist somewhere.
To sum it up - declare an NSUserDefaults object, set objects into it like an NSDictionary, and then synchronize it to save data.
Additional code as requested:
//You have an array named arrayToAdd that has already been created
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[myDefaults setObject:arrayToAdd forKey:#"SomeKeyThatYouMakeUp"];
[myDefaults synchronize];
//You want to get the array out of NSUserDefaults
NSArray *mySavedArray;
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
mySavedArray = [myDefaults objectForKey:#"SomeKeyThatYouMakeUp"];

NSDictionary Not Storing Information

For some weird reason golferStats is not storing info correctly...
I cut out a bunch of stuff in this code to the bare basics why is is still not working?
Problem: The last NSLOG returns nil when it should return a huge array...
NSMutableDictionary *golferStats = [[NSMutableDictionary alloc] init];
golferStats = [userDefaults objectForKey:#"golferStats"];
[golferStats setObject:golferTwoIconCounter forKey:golferName]; //golferName is k
[userDefaults setObject:golferStats forKey:#"golferStats"];
[userDefaults synchronize];
NSLog(#"SAVED SCORE CARD");
NSLog(#"%#",[golferStats objectForKey:#"k"]);
NSMutableDictionary *golferStats = [[NSMutableDictionary alloc] init];
golferStats = [userDefaults objectForKey:#"golferStats"];
...
[golferStats release];
You first create an NSDictionary and then you assign over top of it, thus leaking memory and presumably getting nil back from user defaults. setObject:forKey: in the nil dictionary is a no-op, and then you are setting it back into the user defaults.
EDIT:
Try checking if there is a dictionary first:
NSDictionary *golferStats = [userDefaults objectForKey:#"golferStats"];
if (golferStats == nil) {
golferStates = [NSDictionary dictionary]; // this will not leak
}
...
If you want to preserve the existing contents of the dictionary in cases where it already does exist, do this:
NSMutableDictionary *golferStats = [userDefaults objectForKey:#"golferStats"];
if (!golferStats) golferStats = [[[NSMutableDictionary alloc] init] autorelease];
[golferStats setObject:golferTwoIconCounter forKey:golferName];
[userDefaults setObject:golferStats forKey:#"golferStats"];
[userDefaults synchronize];
// no [golferStats release] because of autorelease above

NSDictionary Inside An NSDictionary

I have the following code:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *golferIconsu = [userDefaults objectForKey:#"golferIconsFirstScene"];
NSMutableDictionary *golferIconsSceneOne = [[NSMutableDictionary alloc]initWithDictionary:golferIconsu];
NSMutableDictionary *savedScoreCards;
NSMutableDictionary *currentScoreCard;
[currentScoreCard setObject:golferIconsSceneOne forKey:#"golferIconsFirstScene"];
NSMutableDictionary *GI = [currentScoreCard objectForKey:#"golferIconsFirstScene"];
[savedScoreCards setObject:currentScoreCard forKey:#"1"];
NSLog([golferIconsSceneOne objectForKey:#"30101"]);
NSLog([GI objectForKey:#"30101"]);
At the end all that is printed out in my log is the first NSLog call, not the second one. For example:
NSLog([golferIconsSceneOne objectForKey:#"30101"]);
This prints out a string that I stored in that dictionary.
This one:
NSLog([GI objectForKey:#"30101"]);
Doesn't print out anything at all.
How can I get the NSDictionary GI to have the exact same properties as golferIconsSceneOne, but I need to do this using the currentScoreCardDictionary, which contains golferIconsSceneOne?
Initialise your dictionary before setting object in it.
NSMutableDictionary *savedScoreCards = [[NSMutableDictionary alloc] init];
NSMutableDictionary *currentScoreCard = [[NSMutableDictionary alloc] init];
Do like this intialize one and set it into other
NSMutableDictionary *savedScoreCards = [[NSMutableDictionary alloc] init];
NSMutableDictionary *currentScoreCard = [[NSMutableDictionary dictionaryWithDictionary:savedScoreCards];