Question

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.

Was it helpful?

Solution 2

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

OTHER TIPS

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.

[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".

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.

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"];

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".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top