Reputation: 592
Here is my mainAppDelegate.h
:
#import <UIKit/UIKit.h>
@interface mainAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property NSMutableArray *toDoItems;
@end
and my mainAppDelegate.m
:
#import "mainAppDelegate.h"
@implementation mainAppDelegate
- (void)applicationWillTerminate:(UIApplication *)application
{
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.toDoItems forKey:@"toDoItems"];
[defaults synchronize];
}
@end
I have another file, XYZToDoListViewController.m
with the code:
#import "XYZToDoListViewController.h"
#import "XYZToDoItem.h"
#import "XYZAddItemViewController.h"
@interface XYZToDoListViewController ()
@property NSMutableArray *toDoItems;
@end
@implementation XYZToDoListViewController
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
XYZAddItemViewController *source = [segue sourceViewController];
XYZToDoItem *item = source.toDoItem;
if (item != nil) {
[self.toDoItems addObject:item];
[self.tableView reloadData];
}
}
- (IBAction)clearData:(UIBarButtonItem *)sender;
{
[self.toDoItems removeAllObjects];
[self.tableView reloadData];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"toDoItems"]){
NSLog(@"toDoItems found");
self.toDoItems = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:@"toDoItems"]];
} else {
self.toDoItems = [[NSMutableArray alloc] init];
}
self.navigationController.view.backgroundColor =
[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_full.png"]];
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, -35, 0);
}
@end
This is at least what I think is relevant. My basic framework is something I followed from this tutorial.
What am I doing wrong? When I add items into my to-do list, terminate the application, then relaunch the app the data i previously entered does not display. There are no errors or warnings on the project, or crashes.
Upvotes: 0
Views: 188
Reputation: 4520
On a totally different side note, I'd like to point out to you that you can change this
if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"toDoItems"]){
NSLog(@"toDoItems found");
self.toDoItems = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:@"toDoItems"]];
} else {
self.toDoItems = [[NSMutableArray alloc] init];
}
To that
self.toDoItems = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:@"toDoItems"]];
Because if you try to get an object that is not set from user defaults (or any dictionary), you get nil back. And if you init your mutable array with a nil array you will have a valid, yet empty, mutable array.
Since it didn't fit as a comment I wrote it as an answer, though of course it has nothing to do with your original problem
Upvotes: 1
Reputation: 14419
applicationWillTerminate:
isn't called I presume, put that userdefault synchronize
code somewhere else.
By the way, when you restart debugger, the process is just killed, not "terminated".
That is why I usually call synchronize
at every change of data, to make sure data is saved in case of a crash, or simply when I restart debugger.
Upvotes: 2
Reputation: 2776
You are not persisting the data. Right now, when you create a item, it lives in memory, but it is never written to the disk, so when the app is terminated, the memory that contained the item is released. You need to write the items to the disk so they can be used after the app is terminated. Either you can archive the items, or you can use Core Data. Don't use NSUserDefaults, which is for user setting.Here is a tutorial for archiving, you can find the Core Data guide on the Apple developer website.
Upvotes: 1
Reputation: 7764
I suppose you don't save the list on the mainAppDelegate class. So, you need to save your data on the class where the list is being formed and delete the invocation your mainAppDelegate. Maybe you're saving a nil value when your app terminate.
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.toDoItems forKey:@"toDoItems"];
[defaults synchronize];
And later you need to invoke it with the same key @"toDoItems".
Upvotes: 0
Reputation: 2413
[defaults setObject:self.toDoItems forKey:@"toDoItems"];
[[NSUserDefaults standardUserDefaults]objectForKey:@"loadItems"]
The 2 don't have the same key. You set @"toDoItems" and try to get @"loadItems".
Upvotes: 1
Reputation: 1853
You'll have an exceptionally difficult time trying to simulate applicationWillTerminate
being called.
I suggest you save your data when it changes (preferred) or at least on something a bit more predictable applicationWillEnterForeground:
or applicationWillResignActive:
.
- (void) applicationWillResignActive:(UIApplication *)application
{
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.toDoItems forKey:@"toDoItems"];
[defaults synchronize];
}
As Emilie Lessard pointed out, you must use the same key to get the right data.
[[NSUserDefaults standardUserDefaults]objectForKey:@"toDoItems"];
Upvotes: 0