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.
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.
Press the home button and double tap it. Now hold the app icon and close it clicking the minus button.
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.




Great Tutorial, Thanks for sharing, submit your this tutorial : Nestdev.com
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
/users/YOUR-NAME/Library/Application Support/iPhone Simulator/YOUR-iOS-SIMULATOR-VERSION/Applications/YOUR-APP-NUMBER/Library/Private Documents
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
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!
Resolved, i think the problem was, that in Xcode 4.1 the “.plist” file should be exact in the Project main folder.
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
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?
Hi, You should use UIApplicationDidEnterBackgroundNotification instead UIApplicationdidenterBackgroundNotification
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.”?
I’m new begin!
Can you share source code for me?
THANKS MUCH
Thanks for this simple way to save and load data
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.
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)’
Works great in Xcode 4.4.1
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 ?
I would like to save a combination of strings and integers. How is it done for saving integers?
Thank you