Saving NSUserDefaults under iOS 4
iOS4 introduced ‘multitasking’ wherein rather than being terminated your application is put into a suspended state where it’ll wait either until the user opens it again, the OS terminates it as it needs the resources or the user taps the ‘stop’ button in the task tray. (Oliver Drobnik has an excellent in-depth explanation of this.)
I encountered a problem today where my application didn’t seem to be saving the parameters I set in NSUserDefaults when the application finishes (I save some state based on the time the user exits. Usually I’d recommend updating the NSUserDefaults object as soon as the user finalises the action rather than at the end of the current application run).
I know some other people have been having this problem too so I thought I’d share the solution, as it’s exceedingly simple.
You need to call the synchronize method on your NSUserDefaults object.
[[NSUserDefaults standardUserDefaults] synchronize];
The OS periodically synchronizes the NSUserDefaults object while your application is running, apparently around every 15 seconds. It seems that when your application backgrounds sometimes it won’t be synchronized in time, if the user kills it from the tray or the OS reclaims the memory immediately. Manually calling synchronize will enforce a save and ensure your data is there next time.
its still not working
everytime i close the app in multitasking and open it again its not saved..
here is my code:
table.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @”Cell”;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict = [array objectAtIndex:indexPath.section];
NSArray *ns = [dict objectForKey:@"Services"];
NSString *text = [ns objectAtIndex:indexPath.row];
cell.textLabel.text = text;
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
NSString *defaultSetting = [stringDefault stringForKey:@"shortSetting"];
if (cell.textLabel.text == defaultSetting) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
[stringDefault setObject:cell.textLabel.text forKey:@"shortSetting"];
[stringDefault synchronize];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 0)
{
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
[self dismissModalViewControllerAnimated:YES];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
}
and in my appdelegate:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
[stringDefault synchronize];
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
[stringDefault synchronize];
}
would be great if you can help me!
greetz
itsfall