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

By
On November 8, 2010

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.