How to make an iPhone App – Part 6: Saving Data

It might not look like so, but your iPhone does have a file system, the thing is that is not the kind of file system that we are used to. To save your data you will only have a directory and you won’t be able to choose it.

If you have an iPhone you might notice that there is no application that has a save button, all your apps save data transparently a few seconds before you quit it.

This is not magic, you have to apply some techniques that i’m going to show you.

When you press the home button, a method called applicationDidEnterBackground is called. To override ApplicationWillTerminate method was the most used way to save data in days previous to iOS 4, now to close an app, you have to send it to background, double tab home button and hold the app icon in the open apps list and touch the minus button.

Today applicationDidEnterBackground method is one of the most used ways to save data, but you have to do some stuff before this.

Open Xcode, and let’s create a View-Based application. I’m going to call it “saveApp”.

Go to the Resources folder and double click saveAppViewController.xib. When Interface Builder loads, drag two text fields (One for a question and one for an answer) and save.

How to make an iPhone App | Saving Data | image 1

In Xcode go to the Classes folder click saveAppViewController.h and add the code for the text fields.

@interface saveAppViewController : UIViewController {
	UITextField *Question;
	UITextField *Answer;
}
@property (nonatomic, retain) IBOutlet UITextField *Question;
@property (nonatomic, retain) IBOutlet UITextField *Answer;
@end

Then connect the objects with the interface elements in Interface Builder. Question is the upper text field and Answer is the lower.

Back in Xcode in saveAppViewController.m add the synthetize statement:

@synthesize Question, Answer;

Nothing new yet.

Saving Data

Now is when we start with the cool stuff. First we need to add a method where we get the directory for our application, saveFilePath. It is going to return a NSString object specifying the path for the directory.

- (NSString *) saveFilePath
{

}

Inside we create a NSArray pointing to NSSearchPathForDirectoriesInDomains it is an object containing the directory, the user domain and a boolean specifying if we want the full path or the relative path, i want the full path.

NSArray *path =
	NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

Finally we return the path but appending an string to the directory, the name of the file. If you don’t do this it is going to return just a directory, and this is not what you want, we want the path for the file. I’m going to call my file safefile.

return [[path objectAtIndex:0] stringByAppendingPathComponent:@"savefile.plist"];

Now your saveFilePath method is:

- (NSString *) saveFilePath
{
	NSArray *path =
	NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

	return [[path objectAtIndex:0] stringByAppendingPathComponent:@"savefile.plist"];

}

Ok, we have our save file. Let’s move to the “saving” method.

As i said before we need to override a method called applicationDidEnterBackground to make it save data to our file.

In that method we are going to add the Question and the Answer to an array and say “Write them to the file”, like this:

- (void)applicationDidEnterBackground:(UIApplication *)application {
	NSArray *values = [[NSArray alloc] initWithObjects:Question.text,Answer.text,nil];
	[values writeToFile:[self saveFilePath] atomically:YES];
	[values release];

}

If you go to saveAppDelegate.m you are going to find that there is also a method called applicationDidEnterBackground. When you close an app the method that is called is the one in the AppDelegate not yours in the viewController, to be called we need to add our terminate method to the dispatch table, and to do so we have to add a few lines of code to the viewDidLoad method in the viewController.m.

Find and uncomment viewDidLoad and add the following lines of code:

UIApplication *myApp = [UIApplication sharedApplication];

[[NSNotificationCenter defaultCenter] addObserver:self
					selector:@selector(applicationDidEnterBackground:)
					name:UIApplicationdidenterBackgroundNotification
					object:myApp];

Now the app will save data, cool. But there is no point in saving data if we don’t load it.

Loading Data

In the viewDidLoad method first call the method to get the path to the file where to read the data. Then, if the files exist, we read and load the data to the Question and Answer objects.

NSString *myPath = [self saveFilePath];

	BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];

	if (fileExists)
	{

		NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
		Question.text = [values objectAtIndex:0];
		Answer.text = [values objectAtIndex:1];
		[values release];
	}

Now the viewDidLoad method should look like this:

- (void)viewDidLoad {

	NSString *myPath = [self saveFilePath];

	BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];

	if (fileExists)
	{

		NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
		Question.text = [values objectAtIndex:0];
		Answer.text = [values objectAtIndex:1];
		[values release];
	}

	UIApplication *myApp = [UIApplication sharedApplication];

	[[NSNotificationCenter defaultCenter] addObserver:self
					        selector:@selector(applicationDidEnterBackground:)
						name:UIApplicationdidenterbackgroundNotification
						object:myApp];

    [super viewDidLoad];
}

Testing the App

Build and run the app. Type a question and an answer.

How to make an iPhone App | Saving Data | image 2

Press the home button and double tap it. Now hold the app icon and close it clicking the minus button.

How to make an iPhone App | Saving Data | image 3

Relaunch the app and the text in the text fields should remain.

Conclusion

There are more complex ways to save data in the iPhone, but this one is just fine for beginners. The next tutorial is the final chapter of this series. I’m going to talk about the final touches you have to give to your app. Cheers.


19 Responses to “How to make an iPhone App – Part 6: Saving Data”

  1. yadirosadi 11. Nov, 2010 at 4:52 pm #

    Great Tutorial, Thanks for sharing, submit your this tutorial : Nestdev.com :)

  2. Luis Sanches 01. Dec, 2010 at 5:17 pm #

    Quick question. How can I find this file (savefile.plist) on the computer? When we create a file this way, where in the filesystem the file is saved?

    Thanks

    • Martin Kabát 21. Jan, 2013 at 3:41 am #

      /users/YOUR-NAME/Library/Application Support/iPhone Simulator/YOUR-iOS-SIMULATOR-VERSION/Applications/YOUR-APP-NUMBER/Library/Private Documents

  3. nick 06. Aug, 2011 at 3:50 am #

    wow thank you so much this has helped me create my first iphone app and is one of my favourites my app isn’t currently out yet though

  4. Edgar Kuskov 31. Aug, 2011 at 6:18 am #

    Hi! First thanks for a great tutorial, but i am having an error:
    SIGKILL: nt retVal = UIApplicationMain(argc, argv, nil, nil);

    exactly when i am removing this app from tray and loading again.

    Thanks for help!

  5. Edgar Kuskov 31. Aug, 2011 at 6:22 am #

    Resolved, i think the problem was, that in Xcode 4.1 the “.plist” file should be exact in the Project main folder.

  6. James Anderson 03. Sep, 2011 at 6:25 am #

    Hello,

    Great tutorial but unfortunately it didn’t load the saved text at all. Is there a way to check that it saved correctly?

    Thanks,

    James

  7. bob 12. Oct, 2011 at 7:44 am #

    Not sure if something has changed (with upgrades to xcode or iOS – note: I am using Xcode 3.2.6 and sdk4.3). But I get the following error when I try to build.

    ‘UIApplicationdidenterBackgroundNotification` undeclared (first use in this function)

    This doesn’t make sense to me as it is just a name string isn’t it?

    • Edson Araujo 12. Oct, 2011 at 9:42 pm #

      Hi, You should use UIApplicationDidEnterBackgroundNotification instead UIApplicationdidenterBackgroundNotification

  8. Edson Araujo 12. Oct, 2011 at 9:58 pm #

    Edgar Kuskov,

    I get the same error “SIGKILL: nt retVal = UIApplicationMain(argc, argv, nil, nil);”, what do you mean with “the .plist file should be exact in the Project main folder.”?

  9. chungnam098 12. Mar, 2012 at 12:00 am #

    I’m new begin!
    Can you share source code for me?
    THANKS MUCH

  10. Ben Reynolds 03. Jun, 2012 at 11:02 am #

    Thanks for this simple way to save and load data :-)

  11. Chelsea 08. Jul, 2012 at 8:54 pm #

    I tried this out a couple different ways and it wasn’t working, but simply changing the line in the saveFilePath from

    return [[path objectAtIndex:0] stringByAppendingPathComponent:@”savefile.plist”];

    to

    return [[path objectAtIndex:0] stringByAppendingPathComponent:@”/savefile.plist”];

    made it work on my iPhone4. ^.^ Simple change that I almost completely overlooked.

  12. Tim 23. Aug, 2012 at 1:56 pm #

    I try to a third text box and I index it at two but every time I run the app it crashes on me.
    It gives me this error.

    Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘-[__NSCFArray
    objectAtIndex:]: index (2) beyond bounds (2)’

  13. Melissa 04. Jan, 2013 at 9:27 am #

    Works great in Xcode 4.4.1 :D

  14. Daniel 02. Apr, 2013 at 8:59 am #

    I have tested the code in my app which saves data from a text field and it crashes. I am using storyboards and the data is being saved from my third screen. Do you have any Idea why my app is crashing when I’m hitting the home button ?

  15. maufox 07. May, 2013 at 2:05 pm #

    I would like to save a combination of strings and integers. How is it done for saving integers?
    Thank you

Trackbacks/Pingbacks

  1. Week 10 – Reflections, Background research supporting material in related to distance dance & communication – Articles, Images & Documentaries- Just Interaction - 28. Nov, 2011

    [...] Saving Data http://mobileorchard.com/how-to-make-an-iphone-app-part-6-saving-data/ [...]

  2. Saving Persistent Data in Xcode iOS Apps | Geek Help Guide - 14. Sep, 2012

    [...] sample implementations I am talking about are here, here, and here, saved for posterity and my own future reference in case things go FUBAR with my [...]

Leave a Reply

© 2008-2051 • Mobile Orchard and the Bar-Tree Logo are service marks. ContactAdvertise