user1214037
user1214037

Reputation: 153

How to use NSUserDefaults with AppDelegate

I am trying to use NSUserdefaults to save some data from a text field, I want it to be saved when the application quits and loaded when the application starts, however I have run into a wall.

The methods that I want to use are all in the AppDelegate, Now I do not understand how to use AppDelegate very well, I have thought of two possible ways to achieve this, I have no idea if it would work though.

  1. Import AppDelegate and over ride the methods inside my VC OR
  2. create an instance of my VC in AppDelegate and allow AppDelegate to set and retrieve the text of my UITextField - (Don't this go against the MVC paradigm?)

Any suggestions would appreciated

Thank you very much for your time

Upvotes: 6

Views: 6189

Answers (4)

danh
danh

Reputation: 62686

Rather than keep the text field in your AppDelegate, keep the text. I'd do the following:

1) In AppDelegate.h:

@property (strong, nonatomic) NSString *textToBeSaved;

2) In AppDelegate.m, read and write textToBeSaved to NSUserDefaults when your app launches and terminates. On launch:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.textToBeSaved = [defaults objectForKey:@"save_me"];

and, before termination:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:self.textToBeSaved forKey:@"save_me"];
BOOL success = [defaults synchronize];

3) In SomeViewController.m that naturally owns the UITextField, in viewWillAppear:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
myTextField.text = appDelegate.textToBeSaved;

4) When you set the textToBeSaved depends on your UI, but whenever you know the text is ready (say on textFieldShouldReturn, or shouldEndEditing), you can hand the string to AppDelegate:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.textToBeSaved = myTextField.text;

If there's no UI to let the user accept the text, you can save the string on (textField:shouldChangeCharactersInRange:replacementString).

Upvotes: 4

hotpaw2
hotpaw2

Reputation: 70673

It's certainly allowed to have the App Delegate hold a reference to the view controller chain. Apple's own examples and iOS app templates often put a pointer to a root view controller in an App Delegate instance variable.

If the view controller chain is not broken, one possibility is to have the App Delegate send a "cleanUpNow" message to the top or root view controller, and have the view controllers pass that down the chain, with every view controller cleaning up as needed and then resending the message to all other controllers farther down the chain to clean up as well.

Reaching directly into another view controller is probably less clean that sending it a message to clean up itself (write to NSDefaults etc.). Of perhaps have them all message a central "clean up" controller object whose purpose is to gather all the necessary state and write it out in one coherent chunk.

If the chain is broken, another option is for the App Delegate to send a notification, with any controllers needed to clean up registering handlers for that "clean up" notification.

Upvotes: 0

Jamie
Jamie

Reputation: 5112

I would suggest you just register for some UIApplication notifications in your subclass and respond to them appropriately. Here is the link to the UIApplication docs. The notifications you can subscribe to are listed at the bottom of the page.

http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html

Here's an example of what you might do in your subclass:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         Selector:@selector(restore)
                                             name:UIApplicationDidFinishLaunchingNotification
                                          object :nil];

Don't forget to remove yourself as an observer as well. There are lots of tutorials online if you're not comfortable with NSNotifications.

Upvotes: 1

erkanyildiz
erkanyildiz

Reputation: 13204

As you mentioned above you have two options:

1-) Directly reach VC's UITextField from AppDelegate's applicationDidFinishLaunching and applicationWillTerminate methods.

On applicationDidFinishLaunching:

Read from NSUserDefaults, set UITextField in VC.

On applicationWillTerminate:

Read from UITextField in VC, set NSUserDefaults and synchronize.

2) Create proper methods in VC to do the same job and call them from AppDelegate.

-(void)record
{
// Read from UITextField, set UserDefaults and synchonize.
}

-(void)restore
{
// Read from UserDefaults, set UITextField.
}

Upvotes: 2

Related Questions