Objective-C NSUserDefaults don't save NSMutableArray for specific key - ios

I have strange problem with NSUserDefaults.
I would like to save NSMutableArray.
I have this piece of code:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:selected forKey:#"markListArr"];
The problem is that the object for key "markListArr" doesn't get saved.
I do this at the first run of the app.
When later in the app I want to save object for that key everything works fine.
If I use any other key everything works fine. I would like to use that specific key because I already have app on app store and this is only update to the existing app.
I already tried [userDefaults synchronize] and it doesn't work.
Any ideas what is happening?

Are you calling [userDefaults synchronize] before fetching the object? I'm using the code below:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *selected = [[NSMutableArray alloc] init];
[selected addObject:#"New Value"];
[userDefaults setObject:selected forKey:#"markListArr"];
[userDefaults synchronize];
NSMutableArray *arr = [userDefaults objectForKey:#"markListArr"];
NSLog(#"arr: %#", arr);
and it prints:
arr: (
"New Value"
)

Related

how to remove an object inside an NSMutableDictionary which is inside a NSUserDefaults

I am trying to remove an object from a dictionary which is in userdefaults.
NSMutableDictionary *userDefaults = (NSMutableDictionary*)[[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
[userDefaults removeObjectForKey:#"XYZ"];
The above code removes the whole dictionary.
XYZ is a NSMutuableDictionary. I want to remove an object with key "Password" from XYZ.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *dict = [[defaults objectForKey:#"XYZ"] mutableCopy];
[dict removeObjectForKey:#"Password"];
[defaults setObject:dict forKey:#"XYZ"];
This should do it:
// Access the dictionary you want to edit as a mutable copy
NSMutableDictionary *dict = [[[NSUserDefaults standardUserDefaults] objectForKey:#"dictKey"] mutableCopy];
// Remove the object for the key
[dict removeObjectForKey:#"keyToRemove"];
// Set the dictionary back in user defaults
[[NSUserDefaults standardUserDefaults] setObject:dict forKey:#"dictKey"];
// Save your changes:
// If you need
// In applicationDidEnterBackground: in iOS >= 7.0
// If you are using iOS < 7.0
[[NSUserDefaults standardUserDefaults] synchronize];

how to save old and new data with NSUserDefault

When I save data using NSUserDefault first time it saves data successfully.When I close my application and start again then I get old data but again I use NSUserDefault with same key.The results is new data comes but my old data does not come.I want both old and new data. So what is the solution for this?
store data
NSUserDefaults *userDefaults ;
if(![[NSUserDefaults standardUserDefaults] objectForKey:#"mydata"])
{
userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:app.arr_defult forKey:#"mydata"];
[userDefaults synchronize];
}
else
{
NSLog(#"Leaderboards Dict Exists %#", [NSUserDefaults standardUserDefaults]);
userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:app.arr_defult forKey:#"mydata"];
[userDefaults synchronize];
}
read DAta :
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
arrayOfImages = [userDefaults objectForKey:#"mydata"];
It's not a good practice to store huge data set in NSUserDefaults.
NSUserDefaults is only for storing small amount of data like app preferences,
setting preferences, etc.
Use Core Data to handle your scenarios.
Everything is fine .just you add new data with same key first you get old data from nsuserdefault and add you both data(old and new) in nsuserdefault.i think is work fine..
// First Time
NSUserDefaults *userDefaults ;
userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:app.arr_defult forKey:#"mydata"];
[userDefaults synchronize];
// second Time
NSMutableArray *temparray1=[[NSMutableArray alloc] init];
[temparray1 addObject:[[NSUserDefaults standardUserDefaults] objectForKey:#"mydata"]];
[temparray1 addObject:app.arr_defult];
[userDefaults setObject:temparray1t forKey:#"mydata"];
[userDefaults synchronize];

How to add objects into NSMutableArray without deleting the existing ones?

Im having trouble with my nsmutablearray in NSUserdefaults, this array every time I relaunch the app erases the objects that already are there and put the new ones, so I need help to prevent these to happen, Thanks and this is my code;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (!self.tasks) self.tasks = [NSMutableArray new];
[self.tasks addObject:textField.text];
[userDefaults setObject:self.tasks forKey:#"tasks"];
//[userDefaults synchronize];
NSLog(#"tasks:%#", [[NSUserDefaults standardUserDefaults]objectForKey:#"tasks"]);
NSLog(#"number of tasks:%d", self.tasks.count);
And Im reading it in a tableview this way:
cell.taskTitle.text = (self.TasksArray)[indexPath.row];
Thanks!
You are missing a line of code there:
self.tasks = [[NSMutableArray alloc] initWithArray:[userDefaults objectForKey:#"tasks"];
As far as I can tell, you're not initially setting your ".tasks" property, so adding that bit may fix the problem.
You need to get it from user defaults first as rmaddy suggests. Your nil check will then create a new array if its never been created/saved before.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.tasks = [[userDefaults objectForKey:#"tasks"] mutableCopy];
if (!self.tasks) self.tasks = [NSMutableArray new];
[self.tasks addObject:textField.text];
[userDefaults setObject:self.tasks forKey:#"tasks"];
//[userDefaults synchronize];
NSLog(#"tasks:%#", [[NSUserDefaults standardUserDefaults]objectForKey:#"tasks"]);
NSLog(#"number of tasks:%d", self.tasks.count);
I see you never call [[NSUserDefaults standardUserDefaults] synchronize];
Once you finish with changes of your object you should call it since it saves your changes to disk.

Adding new object to retrieved NSMutableArray - returns NSInternalInconsistencyException

I keep getting this error when I try to add an object to a retrieved NSMutableArray.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
Retrieve:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arrayOfTitles = [userDefaults objectForKey:#"mainArraySaveData"];
NSMutableArray *arrayOfSubjects = [userDefaults objectForKey:#"subjectArraySaveData"];
NSMutableArray *arrayOfDates = [userDefaults objectForKey:#"dateArraySaveData"];
_mutableArray=arrayOfTitles;
_subjectArray=arrayOfSubjects;
_dateArray=arrayOfDates;
[_tableView reloadData];
Save:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
_mutableArray = [[NSMutableArray alloc] initWithArray:[userDefaults objectForKey:#"mainArraySaveData"]];
[userDefaults setObject:_mutableArray forKey:#"mainArraySaveData"];
[userDefaults synchronize];
_dateArray = [[NSMutableArray alloc] initWithArray: [userDefaults objectForKey:#"dateArraySaveData"]];
[userDefaults setObject:_dateArray forKey:#"dateArraySaveData"];
[userDefaults synchronize];
_subjectArray = [[NSMutableArray alloc] initWithArray: [userDefaults objectForKey:#"subjectArraySaveData"]];
[userDefaults setObject:_subjectArray forKey:#"subjectArraySaveData"];
[userDefaults synchronize];
I'm confused as I thought this was designed to return an NSMutableArray, but it says not - NSArray. What's my issue??
Thanks, SebOH
I'm confused as I thought this was designed to return an NSMutableArray, but it says not - NSArray. What's my issue?
The documentation of the NSUserDefaults talks specifically about this issue in the "special considerations" section of the objectForKey: method:
Special Considerations
The returned object is immutable, even if the value you originally set was mutable.
Fixing this problem is easy - use mutableCopy:, initWithArray: or arrayWithArray: method to make mutable copies:
_mutableArray=[arrayOfTitles mutableCopy]; // You can do this...
_subjectArray=[NSMutableArray arrayWithArray:arrayOfSubjects]; // ...or this
_dateArray=[[NSMutableArray alloc] initWithArray:arrayOfDates]; // ...or this.
User defaults returns immutable objects so you need to call mutableCopy on each before you can modify them.
When you define a variable as NSMutableArray * it is your responsibility to ensure that the instance you store there is of the correct type. The compiler will only tell you that you're wrong if it can tell. In this case the method returns id as you are requesting 'whatever object type exists for this key' from user defaults.

NSMutableArray stored in NSUserDefaults won't save data

When a user signs in through my iPhone app, I create a bunch of default elements in the NSUserDefaults. One of these is an NSMutableArray that I add the following way:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSMutableArray *theArray = [NSMutableArray array];
[prefs setObject:theArray forKey:#"theArray"];
This works flawlessly. However, when I want to insert or retrieve values from theArray, something goes wrong. Here's an excerpt from another file in my app:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[[prefs objectForKey:#"theArray"] setValue:#"This is a value" forKey:#"aValue"];
NSLog(#"%#", [[prefs objectForKey:#"theArray"] valueForKey:#"aValue"]);
I would expect to see "This is a value" in the console when the code has run, but instead I get this:
2011-08-08 18:35:17.503 MyApp[7993:10d03] (
)
How come the array is empty? I've tried the same thing using an NSArray with the same result.
When you store mutable objects to NSUserDefaults, it stores an immutable copy of it so you can't change it directly like that. You have to get the mutable copy out of defaults, change it, and then set it back, replacing old object in defaults.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSMutableArray *mutableArrayCopy = [[prefs objectForKey:#"theArray"] mutableCopy];
[mutableArrayCopy addObject:#"some new value"];
[prefs setObject:mutableArrayCopy forKey:#"theArray"];
[mutableArrayCopy release];
NSArray *savedArray = [NSArray arrayWithObjects:#"obj1",#"obj2",#"obj3", nil];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:savedArray forKey:#"key_for_savedArray"];
[userDefaults synchronize];
//To retrive array use:
NSArray *retrivedArray = [userDefaults objectForKey:#"key_for_savedArray"];

Resources