how to call nsuserdefaults to tableview - ios

i have two textfields and an array.
NSMutableArray *myArray = [[NSMutableArray alloc]init];
[myArray addObject:textFieldHeader.text];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myArray forKey:textFieldGroup.text];
textFieldGroup.text passing to tableview and
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
array = [[NSMutableArray alloc] initWithArray:[standardUserDefaults objectForKey:_passedFieldGroup]];
[self.tableView reloadData];
}
but how do i call these keys as sections and objects as rows when i go to table view?

As far as I understand your problem, you want to go through all of the stored keys in the NSUserDefaults?
That is not possible as far as I know. The only solution that comes to my mind is to store the keys seperate in a file or maybe in an array in the NSUserDefaults, too.

Related

NSUserDefaults save two arrays leading to crash

Recently I was studying NSUserDefaults, then made a demo as follows:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *activity_array = [NSMutableArray array];
NSMutableArray *movie_array = [NSMutableArray array];
[defaults setObject:activity_array forKey:#"activity"];
[defaults setObject:movie_array forKey:#"movie"];
[defaults synchronize];
Then I tried writing the following which I will be calling "code2" for the duration of this post:
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSMutableArray *array = [userDefault objectForKey:#"activity"];
[array addObject:#"123"];
the demo still works.
However the demo crashes when I replace "code2" with the following code:
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSMutableArray *array = [userDefault objectForKey:#"movie"];
[array addObject:#"123"];
As you can see, the difference is the key.
Why does this crash?
NSUserDefaults can store NSMutableArrays, but will turn them into immutable arrays.
Same goes for NSDictionary and NSMutableDictionary.
That means if you want to add an object to an array that you just extracted from the NSUserDefaults, you will have to first make it mutable first, using -mutableCopy for example, or -initWithArray.
NSArray *array = [userDefault objectForKey:#"movie"];
//This works
NSMutableArray *arr = [NSMutableArray alloc]initWithArray:array];
//This works too and is more commonly used.
NSMutableArray *arr = [array mutableCopy];
You can now modify the array arr without any trouble, and you will be able to save it just like you did before. If you retrieve it afterwards, it will be the modified array. But be careful, arrays and dictionaries are always immutable when taken from NSUserDefaults. You will have to do that "trick" everytime you want to modify an array or dictionary from the NSUserDefaults.
EDIT : after testing your code, my only assumption is that your crash-free array is simply nil when you retrieve it. Debug with breakpoints to verify this but I'm close to 101% sure.
EDIT2 : trojanfoe got that faster than I did !
As others have pointed-out the arrays you get back from NSUserDefaults are immutable, so an exception will be thrown when calling addObject: on them, however that won't occur if the array is nil as calling methods (sending messages) to objects that are nil are silently ignored.
Therefore I believe your code2 works as the object #"activity" doesn't exist in the user defaults, while #"movie" does.
Arrays and dictionaries returned from NSUserDefaults are always immutable, even if the one you set was mutable. You'll have to call -mutableCopy.
Try this:
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSMutableArray *array = [[userDefault objectForKey:#"movie"]mutableCopy];
The object from userDefault is not mutable.. Try this
NSMutableArray *arr = (NSMutableArray *)[userDefault objectForKey:#"activity"];
or if you like use id and check its class first to prevent crashing:
id variableName = [userDefault objectForKey:#"activity"];
if ([[variableName class] isEqual:[NSArray class]])
{
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:(NSArray *)variableName];
NSMutableArray *arr = [(NSArray *)variableName mutableCopy];
}
else if ([[variableName class] isEqual:[NSNull class]])
NSLog(#"no object with key:activity");
else
NSLog(#"not array");
//Happy coding.. :)

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.

iOS: Storing selected table view rows in userDefaults

In my app I have a tableview which allows user to enable or disable elements by tapping the rows. Quite simply, I need to store each row's condition in userDefaults - if it's turned on, or not. How would I go about this?
I was thinking I could add a BOOL property to the object each row represents for whether or not its enabled but how would I go about doing remembering the value of the property for each individual object?
You could use some kind of id on each row to be able to identify a particular row. Then you could create an custom object and store it in NSUserDefaults.
Look at this so question
You can just create a bunch of setting keys:
// SET
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:#"setting1_ON"];
[defaults setBool:NO forKey:#"setting2_ON"];
// GET
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
bool setting1 = [defaults boolForKey:#"setting1_ON"];
bool setting2 = [defaults boolForKey:#"setting2_ON"];
Or store one array of all settings (or dictionary):
// SET
NSMutableArray *settings = [NSMutableArray array];
for (UITableViewCell *c in [self.tableView subviews]) {
if (c.selected) {
[settings addObject:[NSNumber numberWithBool:YES]];
} else {
[settings addObject:[NSNumber numberWithBool:NO]];
}
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:settings forKey:#"settings"];
// GET
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *mySettings = (NSMutableArray *)[defaults objectForKey:#"settings"];
setting1 = [mySettings objectAtIndex:1];
setting2 = [mySettings objectAtIndex:2];
On that note, you might consider 2 other options... 1. Just keep all your BOOLs in an array instead of adding them to the cells, then store it when needed; 2. Create a NSObject that is your settings, keep them all in there, and then store the entire object:
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:myApp.settings];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:#"settings"];
To do this you have to add encode/decode stuff to that settings object... there's more on storing custom objects around these parts.

Add NSArray To NSMutableArray

Thanks for you time and reading this. What I'm trying to do is figure out why this NSLog is telling me the NSArray is always null, no matter what. I'm thinking that the problem is that I'm initiating the NSMutableArray wrong. Could you perhaps take a look and decide whether or not I did it right, and if at all possible give me a way to pass the array into the NSMutableArray?
Thanks!
//Get Defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *favoriteArray = [[defaults objectForKey:#"favorites"] copy];
//Declares Mutable Array
self.favorites = [[NSMutableArray alloc] initWithObjects:favoriteArray, nil];
NSLog(#"array: %#", favorites);
UPDATE: I figured it out. It turns out you have to declare it with initWithArray rather than trying to add it as an object
Solution:
- (void)viewDidLoad {
//Get Defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *favoriteArray = [[defaults objectForKey:#"favorites"] copy];
//Declares Mutable Array
self.favorites = [[NSMutableArray alloc] initWithArray:favoriteArray];
[super viewDidLoad];
}
The way to do this is using the arrayWithArray and here is how you do it:
myNSMutableArray = [NSMutableArray arrayWithArray:myArray];
Do you ever set an object in your user defaults for the "favorites" key?

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