iOS SDK: Working with NSUserDefaults

iOS SDK: Working with NSUserDefaults

Tutorial Details
  • Technology: iOS SDK
  • Difficulty: Beginner
  • Completion Time: 30 Minutes (Est.)

In this tutorial I will demonstrate how to use the NSUserDefaults class in order to save and update application settings. In the process, we will build a demo app called “Contact” that will store a user-supplied image and contact information.

What is the NSUserDefaults Class?

With the NSUserDefaults class, you can save settings and properties related to application or user data. For example, you could save a profile image set by the user or a default color scheme for the application. The objects will be saved in what is known as the iOS “defaults system”. The iOS defaults system is available throughout all of the code in your app, and any data saved to the defaults system will persist through application sessions. This means that even if the user closes your application or reboots their phone, the saved data will still be available the next time they open the app!

With NSUserDefaults you can save objects from the following class types:

  • NSData
  • NSString
  • NSNumber
  • NSDate
  • NSArray
  • NSDictionary

If you want to store any other type of object, such as a UIImage, you will typically need to archive it or wrap it in an instance of NSData, NSNumber, or NSString.

Now that you know a bit about what can be done with NSUserDefaults, let’s jump into learning how to use the defaults system with a simple sample app that will store contact information.

Step 1: Creating the Project

Open Xcode and select “Create a new Xcode project”. Select a View-based Application and click Next. Enter a name for your project (I’ve called mine “Contact”). Enter your Company Identifier and make sure you select iPhone for Device Family, because we are going to make an iPhone app. If you are done, click next. Choose a place to save your project and then click create.

NSUserDefaults Figure 1

Step 2: Designing the Interface

In the “Contact” folder in the “Project Navigator” click on ContactViewController.xib.

Drag three UITextFields from the library to the view and arrange them like below. Do the same with a UIImageView and two Round Rect Buttons.

Click The first TextField and type “First name” in the Placeholder text field. Now click the second TextField and type “Last name” in the Placeholder text field. At last, click the third and last TextField and type “age” in the Placeholder text field. For keyboard type, select Number Pad, because you will only need numbers to enter your age.

Change the text of the first button to “Save” and the text of the second button to “Choose Image”.

NSUserDefaults Figure 2

Now we are going the make the connections. Xcode 4 has an new easy and fast way to do so. Select the middle button of the Editor to show the “Assistant editor”.

NSUserDefaults Figure 3

Click the first name TextField and CTRL-drag to the interface. A pop-up will show, enter “firstNameTextField” for name and click “connect.”

NSUserDefaults Figure 3

Do the same with the Last name and age Text Field and the UIImageView, but call them lastNameTextField, ageTextField and contactImageView. For the buttons we need to change the connection to Action instead of Outlet. So CTRL-drag from the save button to the interface, but this time under the curly braces. Change the Connection to Action and enter “save” for name. Do the same with the Choose Image button, but this time enter “chooseImage” for name. Now the code of the ContactViewController.h should read as follows:

#import <UIKit/UIKit.h>
@interface ContactViewController : UIViewController {
    IBOutlet UIImageView *contactImageView;
    IBOutlet UITextField *firstNameTextField;
    IBOutlet UITextField *lastNameTextField;
    IBOutlet UITextField *ageTextField;
}
- (IBAction)save:(id)sender;
- (IBAction)chooseImage:(id)sender;
@end

Now we are done with the interface. Click Build and Run to see if it runs okay. Enter some text and close the app. If you open the app again, you will likely see that the text you entered is still there. If so, this is caused by the built-in multitasking capability of iOS. If you delete the app from the multitasking bar and open the app again, you will see that the text you entered is gone. In this tutorial we will use NSUserDefaults to save the information entered even if you “really” close the app. This will allow the data to persist through multiple sessions.

Step 3: Choosing an Image

Switch back to the standard Editor mode, so you have more space to work within. Open ContactViewController.h and add the UIImagePickerControllerDelegate and the UINavigationControllerDelegate.

<UIImagePickerControllerDelegate, UINavigationControllerDelegate>

If you are done with that, open the ContactViewController.m and scroll down to the ChooseImage action and modify the code to read as follows:

- (IBAction)chooseImage:(id)sender
{
    UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentModalViewController:picker animated:YES];
}

First, we create a UIImagePickerController, then we set the delegate to self. Next, we enable user editing, then set the source type to the photo library, and finally we show it with an animation to the user.

Under choose image action, ad the following image picker delegate methods:

#pragma mark - Image Picker Delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
    contactImageView.image = image;
	[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
	[picker dismissModalViewControllerAnimated:YES];
}

In the first method, we set the contactImageView image to the selected image and then dismiss the UIImagePickerController. In the second method, we only dismiss the UIImagePickerController.

Step 4: Saving the Data

You can save text with the function: setObject:(id) forKey:(NSString *). The key needs to be a specific key for the object you save because you also need that key to get the saved data. You can save integers with the function: setInteger:(NSInteger) forKey:(NSString *). To save the image we first need to create an instance of NSData from it.
Go to the save action and modify the code to read as follows:

- (IBAction)save:(id)sender
{
    // Hide the keyboard
    [firstNameTextField resignFirstResponder];
    [lastNameTextField resignFirstResponder];
    [ageTextField resignFirstResponder];
    // Create strings and integer to store the text info
    NSString *firstName = [firstNameTextField text];
    NSString *lastName  = [lastNameTextField text];
    int age = [[ageTextField text] integerValue];
    // Create instances of NSData
    UIImage *contactImage = contactImageView.image;
	NSData *imageData = UIImageJPEGRepresentation(contactImage, 100);
    // Store the data
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:firstName forKey:@"firstName"];
    [defaults setObject:lastName forKey:@"lastname"];
    [defaults setInteger:age forKey:@"age"];
    [defaults setObject:imageData forKey:@"image"];
    [defaults synchronize];
    NSLog(@"Data saved");
}

First we hide the keyboard. Then we create strings of the text you entered in the first and last name text field. We also create an integer of the age you entered. Than we store the image from contactImageView as an NSData object, because we can’t save a UIImage directly with NSUserDefaults. Then we store the data, we call the standardUserDefaults function to save data in it. At last we synchronize the standardUserDefaults database.

Step 5: Get the Saved Data

At last we want to get the saved data. We do this in the viewDidLoad method, because that method is called when the application opens. Scroll down to the “viewDidLoad” method, uncomment it, and modify the code as follows:

- (void)viewDidLoad
{
    // Get the stored data before the view loads
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *firstName = [defaults objectForKey:@"firstName"];
    NSString *lastName = [defaults objectForKey:@"lastname"];
    int age = [defaults integerForKey:@"age"];
    NSString *ageString = [NSString stringWithFormat:@"%i",age];
    NSData *imageData = [defaults dataForKey:@"image"];
	UIImage *contactImage = [UIImage imageWithData:imageData];
    // Update the UI elements with the saved data
    firstNameTextField.text = firstName;
    lastNameTextField.text = lastName;
    ageTextField.text = ageString;
    contactImageView.image = contactImage;
    [super viewDidLoad];
}

First we call the standardUserDefaults function again, so we can get the saved data. We put the first and last name in an NSString. Although the age is an integer, we create a string to store it, because we can’t directly set the text of an TextField to an integer. We put the image in an NSData object and then we create a UIImage from the NSData object. Finally, we update the UI element with the saved data.

Now that the app is finished, build and run it again. Enter your data and select an image. Close the app from the multitasking bar and then open the app again. The data should still be there this time, and if so, our demo app works!

Thanks for reading this tutorial about NSUserDefaults! If you have questions or comments on this tutorial, leave them in the comments section below!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • NJanf

    Finally a Xcode tutorial. To be honest this site has been flooded with thirdparty-SDK tutorials, most people just aren’t looking for those tutorials.

    • Kirill

      totally agree! we need more sdk’s tutorials.

    • Larry

      They definitely need a lot more Xcode tutorials. The site is getting dry, since I only use xCode. They need an intermediate 6 day tutorial set similar to what they did for leaning objective-c.

      • http://mobile.tutsplus.com Mark Hammonds

        Hey Larry, we actually have an intermediate 6-part tutorial series on building a game in Xcode coming out in about a week or two. We also have a good number of iOS 5 specific tutorials with Xcode currently being written. Hang in there!

  • Rolf

    Its not that i dont liked this one. But i would like to see some more iOS tutorials!
    Maby some advanced or a serie or something.

    • Jeroen van Rijn
      Author

      Maybe you like my Game Center tutorial? It’s an advanced two part tutorial.
      Here are Part 1 and Part 2

  • Nick Stergion

    I am receiving the error “no declaration of property ‘save’ found in the interface.” I am also receiving another error ‘save’ undeclared (first use in this function.) The application will not build and run because of these errors. I also cannot fix-it the errors. The problems are in the beginning of ContactViewController.m @synthesize save, and save release. Can anyone help? I have been following a lot of tutorials and rarely can I complete the projects fully. Thank you

    • Jeroen van Rijn
      Author

      Maybe you have connected the save action as an outlet. If you do this below the curly braces Xcode will create an @property instead of an IBAction. You also don’t need @synthesize save;

      You can download the sample code and compare it with yours, probably something went wrong with the new connection method in xcode 4.

    • http://virtuousgiant.com Nathan Hangen

      This happened to me to because I forget to change the save and choose image to actions and it placed them as @property instead. It also added a few declarations to the header file (.h) so you can just delete them and try again.

  • Doug B

    I agree with the 1st post. The iOS Tutorials are some of the most important and needed, but the site has slowly switched more to Android or 3rd Party Tutorials and I’ve even emailed about it. More Actual iOS Tutorials give more people reasons to return.

  • Bliitzi

    Wonderful, again a little smarter now :)

    Works great, even without property/synthesize. Don’t know why, but it works ^^

  • Sush

    In your tutorial you’ve used NSUserDefaults to save each individual text field. However, if there are multiple contacts using the same text field (ie nib file), how would you save these contact details? I assume you can’t use the same key for multiple contacts?

    • Jeroen van Rijn
      Author

      That’s true. If you want to store more contacts, you use a different key for each contact. But if you want to store a lot off contacts, I think Core Data will be a better way to store those contacts.

  • dharmateja

    Hi, Thanks a lot. It is a very useful example for me.

  • BRLAPP4

    Hey dude great tutorial! I was just wondering if you would be able to give me some advice on how I should go about doing what I’m working on.

    I have one last thing I need to add to my app to wrap it up. What I have done is made a trophy case that consists of 7 trophies all of which are the own IBOutlet ImageView’s and I’m wanting to have it so when the player gets a certain amount of points it unlocks a trophy. My trophies are all dependent on points so if you score 10000 Pts you unlock the first trophy and so on. Now what I need help doing is to be able to define a number stored in NSUserDefaults that will be a single number that is initially 0 and then be able to change that number from anywhere between 0 and 7. Later I want to be able to detect if that number has been changed and from there I will run a method that if one had changed then you have unlocked the corresponding trophy to that number. If you can help or point me in the right direction it would be greatly appreciated THANKS!

    • Jeroen van Rijn
      Author

      Hi, Thanks for reading!

      In the tutorial you can see how to save and get the saved number. You save the number after you reached your score. In your trophy case you can get the saved numer. I think the best way to check what number you have, is with a switch statement.

      I hope this can help you.

      • BRLAPP4

        Hi, Thanks for the reply! I’ve got everything up and running perfectly fine. I’m now going through your Game Center tutorial. Thanks again!

  • Joe

    The line:

    contactImageView.image = image;

    in the delegate method that line is producing an error stating “use of undeclared identifier “image”.

    I thought “image” was a property or iVar already declared elsewhere. Do I have declare this somewhere?

    This has tripped me up on a number of tutorials when the generic use of “image” is being implemented. Anyone have an idea of what habit I have formed in making this happen all the time?

    Thanks,

    I00I

    • Joe

      Now I have moved some things around in my particular project and “image” is declared fine, but “defaults” is not undeclared. Is my problem a question of scope with the ivars? Isn’t NSUserDefaults and UIImage classes declared in Foundation and UIKit meaning shouldn’t I be able to create an instance of NSUserDefaults and UIImage’s without having to declare the instances?

      I am missing a simple lesson is semantics I think?

      • Joe

        I meant to say “defaults” is “NOW” undeclared. Sorry.

      • Joe

        I think I found out what was wrong. I have to redeclare the instance of an object in the different method. I guess each method encapsulates its instances unless they are declared in the header for that particular class? I can see how memory management would start to get hairy if we using alloc, copy, retain in these situations.

  • John

    I didn’t manage to store the int type into NSUserDefaults and so had to convert to an object (NSNumber) to get it to accept (or i could have easily as left it as a NSString object as received from the text field).

    Nice tutorial, even had to think for myself too!

  • Susan

    What if I wanted my “SAVE and LOAD” code block to automatically load on launch… and save on exit… without forcing the user to constantly hit pointless SAVE and LOAD buttons?

    Where would I place my NSUserDefault code blocks?

    • Jeroen van Rijn
      Author

      You can place the SAVE block in the viewWillDisappear: method and the LOAD block in the viewWillAppear: method.

      I hope this can help you!

  • http://www.mdgtechnology.com Micke De Geer

    Hi Jeroen!

    Nice tutorial! I’m looking for a way to have in app settings and this seems like a nice way to go about it. How can I do to have an initial (default) value in the fields which then later may of course be overridden by the user?

    Thanks!

  • Micke

    Hi again!

    I thought a little more on this and came to the conclusion that I could of course include a file in the bundle that contains the initial default values. The first time the user starts the application I then read the values from the file in the bundle and save them using NSUserDefaults. I also need a flag (also stored in NSUserDefaults) to tell me if this is the first time or not. In fact, I probably only need the flag, I can have the initial values in the code…

    Will try this now :)

  • khushi

    Hi,

    Gud tutorial. How to store and retrieve array in NSUserDefault ?

    • Jeroen van Rijn
      Author

      Hee, thanks!

      You can save an array like this:

          NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
          NSArray *myArray = [NSArray arrayWithObjects:@"hello", nil];
          NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myArray];
          [defaults setObject:data forKey:@"myArrayKey"];
          [defaults synchronize];
      

      And retrieve the array this way:

          NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
          NSData *data = [defaults objectForKey:@"myArrayKey"];
          NSArray *myArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
      

      I hope this will do it for you!

  • Micke

    Hmm…I’m having trouble getting this to work after closing the app from the multitasking bar. It works fine otherwise. It appears that my data isn’t persistent over app termination. I’m doing synchronize but not registerDefaults…

    Any ideas anybody?

    • Micke

      OK – got it working! Stupid mistake as usual :). Looked thouroghly at your code and at AppPrefs (Apple Sample Code) changed some things and then (not much) it worked…believe it had to do with interpreting nil correctly.

  • Omer

    Nice tutorial!
    can u please tell us that how can we use it if we want to navigate from this view to another view by clicking a button, like if we use this Save button as a login button … ?

    please do a favor

  • Mats

    Hi Jeroen,

    Thank You very much for this great tutorial. I’ve created prefs in an app which already existed by adding a settings bundle and modifying it to my needs. This all workers fine. In the settings app I can change all the data. But reading them gives difficulty. My app contains several custom views with drawing in the drawrect method. Where should I put the commands for reading up the defaults? Should I add a viedDidLoad method or should I put the code in the drwrect method? Neither seems to work. Any ideas?

    Thnx, Mats

  • Tim

    Great tutorial

    Question:

    I have a UITableView and when a user clicks on a row a new view is displayed. I am able to them fill the information out and save it as instructed by your steps. However when I click on a different row it displays the information that was entered in the previous row.

    How do I manage to show different saved information per each row?

    Thanks

  • PC

    Hi,

    Great tutorial but having a really annoying issue. App works fine, however if i close the app in the multitask bar and reopen the app, i get a sigkil error.

    Any ideas?

  • PC

    Nope doesnt matter, works fine on iphone, seems its an issue with simulator!

  • http://www.bennarts.com Gary Benna

    If I want to save the data ( an image, name, and date) as one group with its own name or key. How would I do that so I could call It back later as a group/

  • http://wpguru.co.uk Jay Versluis

    Lovely tutorial, thank you so much ;-)

    Sadly Apple’s constant Xcode updates mean that with a minor release they made certain things “illegal” and others just “annoying”. I’m running Xcode 4.3.2 here and I’m getting a coupe of issues.

    First, Xcode thinks that declaring without an ID is now “archaic”.

    The other issue is that picker.delegate = self throws the warning “Assigning to ‘id ‘ from incompatibel type ViewController *const__strong”

    Needless to say, I haven’t got a clue what any of that means – but my screen is blank and it won’t work. I get no other errors or warnings in the code. Any idea how to prevent those warnings? What’s the Xcode 4.3.2 way of doing this (which will be outdated by the time Xcode 4.3.3 comes out of course)…

  • http://wpguru.co.uk Jay Versluis

    Ah, my mistake – I put the UIImagePickerControllerDelegate, UINavigationControllerDelegate in the wrong place, I was under the assumption that it should go at the top of the file, instead it needs to go underneath the first @interface directive.

    Looks all good now, no more warnings.

    Saving the values and retrieving them works well, however when I choose an image it crashes the app on both iPad 2 and iPad 3.

  • neha

    I’m doing 1 application in that app previously entered data is also appearing when I’m running my application next time. i don’t want that data to appear next time. can u help me?

  • pavan

    Hi,
    simple and nice tutorial,but in my code when i click on every textfield keyboard is not hidden.

    Plz give reply.

  • http://www.mcfoxteam.com Ishan

    nice tutorial for getting the basic idea about userdefaulst

    can u tell how to store
    1- NSData
    2- NSMutableArray
    In user defaults and retrieve it

    • ishan

      I need only NSMutalbe Array

  • Emon

    Simply excellent example.

    Now i have a request to administrator is that can you provide a sample or example like that where those thinks will include:

    1.One table view with task name list..

    2. new task add button at the navigation bar.

    3. new task will save name, location and time

    4. there should be a delete option of task from the table.

    5. using local notification show the task alert using the task time.

  • Tuhin

    Thanks for the tutorial. Really Helpfull.

  • ana

    Thanks for sharing this tutorial. you explained it perfectly clearly. and i’m glad you included the array handling in the comments section.

  • Manju

    Hi,
    Thanks for the tutorial. I tried the following code to save data NSString *xData = [numX text];
    NSString *yData = [numY text];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:xData forKey:@"xData"];
    [defaults setObject:yData forKey:@"yData"];

    [defaults synchronize]; in applicationWillTerminate class but it does not seem to be saving it when I kill app and open it again. I load the data in viewDidLoad( tried in viewDidAppear too) but nothing works.. Pls help… I tried saving data in viewWillDisappear and applicationDidEnterBackground, but same results…

  • Hector

    Thanks! Great tutorial, exactly what i needed.

  • Mohammad Aamir Ali

    Great post. Thank you very much

  • kartik

    realy nice tutorial..u made it look so easy !!thankyou….

  • Ad

    Really a nice and self explanatory tutorial. I am really enchanted that i learnt this thing so easily…

  • Saakar

    a tutorial with very nice demonstration including snapshots. It helped me lot.Really thanks for wonderful illustration.
    But admin can you give me example in this that how can i clear or reset all the saved data to initial stage on a button tap say ‘Remove’ so that when Remove is tabbed all data are gone and when user loads the application again there is nothing on firstname, lastname, age and image.
    please..
    thanks in advance..

  • Manish Saini

    i have learn more thing and now i m clear about UIUserDefault class…this example so easy for why to use UIUserDefault class…thank you so much

  • sri

    Really a nice tutorial.keep going

  • tp2

    Snx for tutorial, but it don`t save data in my case… please help, if you can…
    my proc:

    - (IBAction)save:(id)sender {

    NSString *savingServerAddress =
    [self.serverAddress text];

    NSString *savingLogin = [self.login text];

    NSString *savingPassword = [self.password text];

    // Store the data

    NSUserDefaults *defaults = [NSUserDefaults
    standardUserDefaults];

    [defaults
    setValue:savingServerAddress forKey:@"savingServerAddress"];

    [defaults setValue:savingLogin
    forKey:@"savingLogin"];

    [defaults setValue:savingPassword
    forKey:@"savingPassword"];

    [defaults synchronize];

    NSLog(@”Data saved”);

    }

    breakpoint at NSLog(@”Data saved”); show this

    Printing description of defaults:

    Printing description of *(defaults->isa):

    (Class) [0] =

    Printing description of defaults:

    (NSObject) NSObject = {

    isa = NSUserDefaults

    }

    Printing description of defaults->_unused:

    Printing description of defaults->_reserved:

    (void *[4]) _reserved = {

    [0] = 0×00000000

    [1] = 0×00000000

    [2] = 0×00000000

    [3]
    = 0×00000000

    }

    • tokke

      You’re using:
      [defaults setValue:savingPassword forKey:@"savingPassword"];

      You should use:
      [defaults setObject:savingPassword forKey:@"savingPassword"];

  • Salman Khan

    nice tutorial

  • Baruch Kly

    Really perfect! Talented author no doubt.

  • Eric

    can any body tell me from where i can get the list of tutorials posted by this forum…..

  • mihata

    A little outdated but still useful