Property List Tutorial – using plist to store user data

This tutorial is the first I’m going to do in a series of tutorials dealing with data in our apps. The series will include different ways to bring data into our app as well as ways to save data from our app to use the next time the app is launched. I’m going to start with property lists or plists as they are often called.

Property lists are a convenient way to access and store small amounts of data. You cannot store custom data objects in a plist, only standard types such as String, Integer etc … as well as collections of standard types. Plists most commonly stored in XML format though they can also be stored in binary form. Property lists are very user friendly because there are methods already in place to store an object or array of objects as a plist xml document and to then other methods to read a plist xml document and convert it back into an object or dictionary etc … What this means is you don’t have to do the parsing of the xml yourself.

The App

We’ll be talking more about this in future tutorials, for now we are just going to create a very simple property list as an xml document, save some data to it, and then read that data back out of the plist the next time we run the app.

For more information on plists refer to Apple’s documentation.

1.) Create a new View-based Application named PlistTutorial.

2.) Right click on Supporting Files and elect New File, then under iOS select Resource and then Porperty List and name it Data.plist.

Create Empty File

3.) Double click on Data.plist in Xcode to open it up there and add a String “Name”, and an Array “Phones” which has three items. You can add the items by clicking on the little symbol

Tweet Header File

on the far right edge of the line that says root.

Add to the plist

Edit the fields by clicking in them and then typing.

Change the plist element value

After adding the Name String select Root again to display the add icon and repeat the process to add the Array.

add another variable element to the plist

set the data type of the element

Then click the little arrow next to Phone and it will display the add icon so you can add items to the array.

add item to the array

It should look something like this when you are done. You can change the order of the elements just by dragging them.

finished plist

4.) Open up PropertyListExampleViewController.h and add six variables to it and two IBActions. It should be fairly obvious what these are so I won’t go into them in detail. The textFieldReturn method will be used to dismiss the keyboard when the return key is pressed, saveData will get called from a UIButton in the user interface.

#import "UIKit/UIKit.h"

@interface PlistTutorialViewController : UIViewController 
{
	
	IBOutlet UITextField	*nameEntered;
	IBOutlet UITextField	*homePhone;
	IBOutlet UITextField	*workPhone;
	IBOutlet UITextField	*cellPhone;
	
	NSString		*personName;
	NSMutableArray	*phoneNumbers;
	
}

@property (nonatomic, retain)	UITextField		*nameEntered;
@property (nonatomic, retain)	UITextField		*homePhone;
@property (nonatomic, retain)	UITextField		*workPhone;
@property (nonatomic, retain)	UITextField		*cellPhone;

@property (nonatomic, retain)	NSString		*personName;
@property (nonatomic, retain)	NSMutableArray	*phoneNumbers;

- (IBAction) saveData;
- (IBAction) textFieldReturn:(id)textField;

@end

Then open up the implementation file and synthesize those variables.

#import "PlistTutorialViewController.h"

@implementation PlistTutorialViewController

@synthesize personName;
@synthesize phoneNumbers;
@synthesize nameEntered, homePhone, workPhone, cellPhone;

5.) Create the user interface, and link up the user interface elements to appropriate IBOutlets. If you need help with this check out one of the tutorials on building a user interface. You just need to make it look something like this.

UI View

Connections Inspector

You need to link each of the UITextField’s to the IBAction textFieldReturn as well and select Did End On Exit. This will allow us to dismiss the keyboard when we press the return key.

Link the UIText Fields to the IBAction

6.) Open up PropertyListExampleViewController.m. We’re going to retrieve the Data.plist file in the viewDidLoad method, and set the textFields in our user interface to the values retrieved from our Data.plist. I’m going to let the comments describe what is going on.

- (void)viewDidLoad 
{
    [super viewDidLoad];
	// Data.plist code
	// get paths from root direcory
	NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
	// get documents path
	NSString *documentsPath = [paths objectAtIndex:0];
	// get the path to our Data/plist file
	NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Data.plist"];
	
	// check to see if Data.plist exists in documents
	if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) 
	{
		// if not in documents, get property list from main bundle
		plistPath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
	}
	
	// read property list into memory as an NSData object
	NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
	NSString *errorDesc = nil;
	NSPropertyListFormat format;
	// convert static property liost into dictionary object
	NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
	if (!temp) 
	{
		NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
	}
	// assign values
	self.personName = [temp objectForKey:@"Name"];
	self.phoneNumbers = [NSMutableArray arrayWithArray:[temp objectForKey:@"Phones"]];
	// display values
	nameEntered.text = personName;
	homePhone.text = [phoneNumbers objectAtIndex:0];
	workPhone.text = [phoneNumbers objectAtIndex:1];
	cellPhone.text = [phoneNumbers objectAtIndex:2];
}

7.) Save everything, Build and Run and at this point and you can see that the values in Data.plist are being read and populating the UITextFields.

Simulator Shot 1

8.) Now we’ll write the Data.plist file with values taken from our UI. Implement the method saveData in our view controller implementation file and write the values in the UITextFields back to our Data.plist file. Again I’ll let the comments explain what is going on.

- (IBAction) saveData
{
	// get paths from root direcory
	NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
	// get documents path
	NSString *documentsPath = [paths objectAtIndex:0];
	// get the path to our Data/plist file
	NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Data.plist"];
	
	// set the variables to the values in the text fields
	self.personName = nameEntered.text;
	self.phoneNumbers = [[NSMutableArray alloc] initWithCapacity:3];
	[phoneNumbers addObject:homePhone.text];
	[phoneNumbers addObject:workPhone.text];
	[phoneNumbers addObject:cellPhone.text];
	
	
	// create dictionary with values in UITextFields
    NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: personName, phoneNumbers, nil] forKeys:[NSArray arrayWithObjects: @"Name", @"Phones", nil]];
	
	NSString *error = nil;
	// create NSData from dictionary
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
	
    // check is plistData exists
	if(plistData) 
	{
		// write plistData to our Data.plist file
        [plistData writeToFile:plistPath atomically:YES];
    }
    else 
	{
        NSLog(@"Error in saveData: %@", error);
        [error release];
    }
}

9.) Now implement the textFieldReturn IBAction in our view controller implementation method so that we can dismiss the keyboard.

// we use this to dismiss the keyboard when the return key is pressed
- (IBAction) textFieldReturn:(id)textField
{
	[textField resignFirstResponder];
}

10.) Save everything, Build and Run and test it out. When you enter new data into the text fields and click the save data button, it should get saved to the Data.plist file and then be read in the next time the app is loaded.

Final Simulator Shot

Here’s the code.



This entry was posted in Data and tagged , , , , , , , , , , , . Bookmark the permalink.

90 Responses to Property List Tutorial – using plist to store user data

  1. FB says:

    Thank you for this tutorial :)

  2. kuldeep says:

    where i get the sample code for this tutorial

  3. Red says:

    When I open data.plist file (in Resources Folder in Xcode) it still has the original values, even though I had changed it on the App Simulator. When I click home or exit in the Simulator and load the program again it had the new values which I had entered.

    Should the values change in the data.plist (in Resources Folder in Xcode)? Or is there another location I should look to see the change in the plist?

    Thank you so much for this tutorial.

    • Kent says:

      Very good question. The short answer is you are looking at the wrong data.plist file, but it’s not so obvious until you dig in.

      Here’s the long answer.

      The plist we create in our Resources folder resides here on our file system.

      /Users/yourUserName/Library/Application Support/iPhone Simulator/4.2/Applications/Your unique app id number/PlistTutorial.app/Data.plist

      But when we save the data into our plist we are saving it to our documents directory in the app which resides here on our file system.

      /Users/yourUserName/Library/Application Support/iPhone Simulator/4.2/Applications/Your unique app id number/Documents/Data.plist

      So we’re not actually saving to the plist that we created. But we are saving it in the correct place because we want to save it to the documents directory.

      So then the question is why did we bother to create the plist in the resources folder? Well the first time the app runs it looks in the documents folder for the plist, if it doesn’t find it there it then tries to get the plist from the main bundle. So when it doesn’t find the plist in the documents folder, because we haven’t done a save and created it there yet, it gets the plist file we created in our Resources folder and uses it the first time. From then on after we save the data it will find the plist in the documents folder and use it. If we hadn’t created that plist file in the Resources folder we’d get an error the first time when we try to create the dictionary because our xml would have no data.

      If you want to see the changes in the plist file each time you do a save look at the plist in the documents directory.

      /Users/yourUserName/Library/Application Support/iPhone Simulator/4.2/Applications/Your unique app id number/Documents/Data.plist

      If you want to get a better understanding of this than my explanation above may have given, try adding a breakpoint to the beginning of the viewDidLoad method and playing around with it. Change the name of the plist in both the retrieval process and the save process and try deleting it from the Resources folder both before and after you have done a save. Try it in every different scenario you can think of. You’ll get a real good feel for what is happening.

      Hope this helps.

  4. Premkumar says:

    sir how to add the add button to this project and we will click add buttons means new plist will be create plz help me….

    • Kent says:

      Are you saying you would like to create the plist programmatically after the user clicking a button?
      Hmmm, I’ll have to think about that one.

      • Kent says:

        Okay I don’t have time at the moment to make this into a tutorial, will as soon as I can. But in the meantime if you want a sample app and some code for doing this you can go to http:www.theappcodeblog.com/code/PlistButtonTest.zip

  5. Winona says:

    Hi! I followed your tutorial closely but I couldn’t run the application! As in, the application closes after I build and run it. :( When I commented out -(void)viewDidLoad, the application was fine…. Is there anything wrong or I could have missed out on? Please help me… Thanks!!

    • Kent says:

      ViewDidLoad is where most of the code to retrieve the plist happens. Something must be going wrong there. Try posting the code for your viewDidLoad method here.

  6. Winona says:

    Hi, below is my code for viewDidLoad :

    - (void)viewDidLoad {
    [super viewDidLoad];
    //Data.plist code
    //get paths from root directory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    //get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    //get the path to the Data.plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Data.plist"];
    //check to see if Data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
    //if not in documents, get property list from main bundle
    plistPath = [[NSBundle mainBundle] pathForResource:@”Data” ofType:@”plist”]; }
    //read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    //convert static property list into dictionary object
    NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    if (!temp) {
    NSLog(@”Error reading plist: %@, format: %d”, errorDesc, format);
    }
    //assign values
    self.personName = [temp objectForKey:@"Name"];
    self.phoneNumbers = [NSMutableArray arrayWithArray:[temp objectForKey:@"Phones"]];
    //display values
    nameEntered.text = personName;
    homePhone.text = [phoneNumbers objectAtIndex:0];
    workPhone.text = [phoneNumbers objectAtIndex:1];
    cellPhone.text = [phoneNumbers objectAtIndex:2];
    }

    Thank you so much for helping me!!! :D

    • Kent says:

      Well the problem is not in viewDidLoad, I plugged your version in and it still ran fine. Are you getting an error in the console? Can you add a breakpoint and run in debug mode and pinpoint where exactly the app is crashing?

      This is a pretty small, straight forward app, let me know if neither of the above help and you can email me your app and I’ll take a look. Not much else I can do without seeing all your code.

  7. Winona says:

    Hi, can I have your email so that I could email you my codes? Really thanks a lot for helping!!

    • Kent says:

      You can send it to
      kent
      @
      theappcodeblog
      .com

    • Kent says:

      Hi Winona, well I can’t find anything wrong with your code. I tried all kinds of stuff and even replaced your code with code I knew was good and it still kept crashing. Finally I deleted your plist and replaced it with one I knew was good and it worked. So then I deleted it and created a new plist and it also worked.

      All I can say is your plist is bad. I don’t know why and I can’t see anything wrong with it. But I think if you delete it and create a new one following steps 2 and 3 above it will work for you.

      Let me know how it goes. I put some time into this trying to figure it out so I’m interested if creating a new plist works for you too.

      Good Luck!

  8. Winona says:

    Hi! I’ve sent the codes to you already. Thank you so much!

  9. Winona says:

    Hi Kent, so sorry for wasting your precious time. I’ve realized where my problem is at. For my plist.data, I’ve inserted “phone” instead of “phones”. That’s why the app crashed when I tried to run it. Thank you so much for your help! Really sorry to waste your time…

  10. Winona says:

    Sorry about that!

  11. Winona says:

    Oh, when I save the data, does it change the values in Data.plist?

  12. Jim says:

    I was having trouble also until I deleted the “Root” line in the Data.plist file. It shows in your sample above but not in your actual code. So removed it and it then worked. Any ideas?

    • Kent says:

      Jim, did you create a key named Root? The Root in a Plist is the outermost node. In fact if you open the Plist in a text editor it won’t even show up. Creating your own would definitely lead to a problem. But you can’t delete the Root from a Plist that I’ve seen.

      • Jim says:

        Kent,
        Yes, I did create a key named Root per your view above which shows a key “Root”. However, I am using iPhone 4.3 simulator which does not show the Root in the editor, therefore I mistakenly created it to look like the view above. Again… once it was removed, from the 4.3 editor, had to rebuild plist, all worked. Thanks for making tutorial easy to follow except for the versioning issues.

        • Kent says:

          I updated to 4.3 a couple weeks ago so from here on the versioning should not be an issue for you.

          Glad you got it working and thanks for reading.

  13. JANE says:

    HI,
    HOW DO WE STORE IMAGE AND RETREIVE THE IMAGE FROM THE PLIST?

    THANKS

  14. jane says:

    Hi,

    Can i know how to add images into plist?

    • Kent says:

      Hi Jane,
      Property lists can only hold NSString,NSArray,NSDictionary,NSData,NSDate,NSNumber or boolean values.
      You can add the name of an image to the Plist, but not the actual image itself.

  15. bea says:

    Hi,

    I followed the tutorial exactly, but every time I add new data, it overwrites the existing data. Is there a way to append the plist so it can collect multiple entries that could be displayed in a table? Thanks for your help.

    • Kent says:

      A plist can hold an array so you could keep adding to the array if you really wanted to. A plist is read all at once so it is a memory hit with too much data. To use an array you would need to read the contents of the array then add to the array and then save it again.

      My guess is you would be better looking for a different way to save your data if you are going to be adding to it regularly. Take a look at the Core Data tutorials.

  16. Poster says:

    nice tutorial thanks! also awesome yellow color :-)

  17. naSh says:

    Hi Kent!

    A simple question. What should I tweak in order to save that same plist in a remote server? In that way different users could access the data and update its contents. Is it a simple command or is it a whole bunch of new code? I would think is as easy as posting the info in an http or ftp and adding your user name and password….

  18. Andy says:

    Thanks for the tutorial it’s very well written and easy to follow. I have found it very useful but I was hoping you could help me solve a problem I’ve been having for the last few days.

    I am populating a table view with data from a Plist and users can make multiple selections using a check mark, but I am having difficulty implementing your methods to save their data.

    Each time they make a selection a Boolean value in the Plist updates fine but I can’t get it to save.

    Any help would be hugely appreciated.

    Thanks

  19. Zachary says:

    Hi Kent,
    Great Tutorial.

    How to add more data to the plist?
    Try to figure out also how to get the data to show it table view.

    Thanks

    • Kent says:

      I would suggest you might be wanting to use Core Data instead. If you are asking how you would create more records of the same type I would suggest Core Data. The fact that you want to display them in a table also points to this. Have a look at the Core Data tutorials.

  20. Pingback: Reading from and writing to plists in xcode 4.0.2 – issue retrieving from dictionary | taking a bite into Apple

  21. rox says:

    hi,
    i have used this program in my app, and the saving thing works perfectly fine. But I am not able to access the saved data.plist. I read your answer to red, but the link isn’t clear, could you please tel me in steps what i need to do to access that file?
    thanks very much. i will really appreciate it.

    • Kent says:

      You just need to follow the directory to the correct file.

      /Users/yourUserName/Library/Application Support/iPhone Simulator/4.2/Applications/Your unique app id number/Documents/Data.plist

      So start at your hard drive and go into the Users folder. Then go into your folder (whatever your user name is, I can’t tell you what you named it). Then go into Library, then into Application Support, then iPhone Simulator, then 4.2 or whatever version you are using, then Applications. Again these are all just folders so just double click them to open them up. Now at this point you will be in the Applications folder and depending on how many apps you are working on you will see folders with names that don’t mean much. Here’s an example of what one of mine is named.

      2DD0EFF7-42C3-40C2-9709-FE4F6346E909

      You’ll have to determine which on of these is the app you are wanting. When you do open up that folder and then the Documents folder. In the Documents folder you will find the plist you want to look at.

      Good Luck!

  22. rmsh26 says:

    Thanks Kent, good tutorial.
    It worked for me :-)

  23. rmsh26 says:

    Can any one suggest iphone book which is fully programmatic based, book without using interface builder.As i want to become more strong in iphone programming.
    For Objective-c (Peachpit.Press.Objective.C.Visual.QuickStart.Guide.Feb.2010), this Peachpit book is easy and good.

  24. Vishal says:

    Heyy…m very new to xcode and my teacher gave a very hard assignment which i hv to complete witin this weekk m sendin u its detail to your e mail id plz plz plzzzzzzz help me in that..:(…your this tut was really helpfull….but need some more help…

  25. Vishal says:

    i cant send u mail on your email id so m writin my big problm hea:P…this tutorial woz realy very helpful to me…it made me move 1 step forward……bt m far from ma destination nd i got to reach dr asap. i have been given assignment that when i press add button then a form should opn with many textfields and the data v enter in textfield should get saved into plist……i used the code which was in your plist but i wanted to know that when i run the application for the 2nd time and entr new data then where it will get saved??i’ve been told to save that data in same plist without deletin the previously added data in plist……so that when we pres a button “display”…aal the namez which hv been aded to plist should appear…just the name not phone numbers…and more..your complete code worked my plist creasted in documnts but juss 1 thing that dint work is my keyboard is not getting dismissed..:(..and that keyboard hides my save data button..:(…pls plss plss reply asap..its ma humble request…i know i wont b able to help u in anyway in future but ..:(.jus hoping u will reply..:)..adios.

  26. Shai Levit says:

    how can you assure that the correct information is being displayed when there are several drill down methods for a pList.
    So say I start with Array -> Dictionary -> Array -> Dictionary ->string….
    Where each Array may also have its own Strings.
    But in the NSString *path = [[NSBundle mainBundle] pathForResource:@”nameofplist”
    of Type:@”plist”];

    It does not drill down appropriately. Is there a mechanism to assure a correct drill down method?

    regards

    Shai

  27. Ranjit says:

    Hi Kent I want to store an array of arrays which is filled with custom objects..so how I can write/read that..please help me out

    Regards
    Ranjir

  28. Ranjit says:

    Hi Kent I want to store an array of arrays which is filled with custom objects..so how I can write/read that..please help me out

    Regards
    Ranjit

  29. Clivt says:

    Thank you for the tutorial.

    This is really great for newbie.

  30. sakthi says:

    Hi kent,
    Amazing tutorial.
    My question is, whether is it possible to insert a sequence of records into the .plist file.
    In my application i am having lot of songs to play, if i wants to save more than one songs to the favorites list, where i have to store it and display to the user.

  31. Satyam says:

    hi kent ,
    this app is storing only one name and his phone numbers,
    so by writing this we get only one recored ,,,,
    //assign values
    self.personName = [temp objectForKey:@"Name"];
    self.phoneNumbers = [NSMutableArray arrayWithArray:[temp objectForKey:@"Phones"]];
    //display values
    nameEntered.text = personName;
    homePhone.text = [phoneNumbers objectAtIndex:0];
    workPhone.text = [phoneNumbers objectAtIndex:1];
    cellPhone.text = [phoneNumbers objectAtIndex:2];

    if i want to store more names phones and and retrieve the phone numbers using particular “name ” by searching dictionary ….
    how to do that ? can it be done…?
    plz reply
    thanks

  32. Go Inspired says:

    Thanks for this info! I was looking for something like this.

  33. obaid says:

    Hi, I have got many things learnt from here, but I’m stuck at one place i’m using Alertview for taking the input from the user, and i want to store user input to the nsdictionary, or plist or anything because i want it to be stored. So for that I have used the UILabel to store the user input and save it, but as soon as I switch to other class xib the UILabel user input is becoming default as Label. Here is the following code which I’m using, please help
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@”Hello!” message:@”Please enter your name:” delegate:self cancelButtonTitle:@”Continue” otherButtonTitles:nil];
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    UITextField * alertTextField = [alert textFieldAtIndex:0];

    alertTextField.keyboardType = UIKeyboardTypeDefault;
    alertTextField.placeholder = @”Enter your name”;
    [alert show];

    NSString *done1=[NSString stringWithFormat:@"%@",highscorename.text];
    // Create the dictionry
    NSMutableDictionary* myDict1 = [[NSMutableDictionary alloc] init];

    // Add objects to dictionary
    [myDict1 setObject:done1 forKey:@"Highscore1"];

    // Get the path
    NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath1 = [paths1 objectAtIndex:0];
    NSString *path1 = [documentPath1 stringByAppendingPathComponent:@"highscore1.save"];

    // Save to file
    [NSKeyedArchiver archiveRootObject:myDict1 toFile:path1];

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    NSLog(@”Entered: %@”,[[alertView textFieldAtIndex:0] text]);
    highscorename.text=[NSString stringWithFormat:@"1%@",[[alertView textFieldAtIndex:0] text]];

    }

    Then in Viewdidload the code I’m using is

    // Get the path
    NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath1 = [paths1 objectAtIndex:0];
    NSString *path1 = [documentPath1 stringByAppendingPathComponent:@"highscore1.save"];

    // Create a dictionary to hold objects
    NSMutableDictionary* myDict1 = [[NSMutableDictionary alloc] init];

    // Read objects back into dictionary
    myDict1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
    highscorename.text= [myDict1 objectForKey:@"Highscore1"];
    NSLog(@”%@”,highscorename.text);

  34. rohit says:

    I am using Xcode 4.2 on lion. When I try to create new plist file , its creates an empty plist file and I am unable to add any values to it. There are no buttons or anything to add new data to empty plist file.

  35. Casey says:

    So not sure if this has been commented on yet.. But I think I found a mistake in your code. The plist that you are creating in your saveData method (plistDict) dose not retain its values if you delete the app from the multitask bar then try re-running it.

    Now I might be wrong (in that i slightly changed your read method so that it was a singleton and would only ever be used once at a time. but everything else is the same and it most definatly dose not retain values in plistDict… I tested the ceap out of it lol…

    anyway I fixed this issue but using the dictionary in your read function (temp). Basicly I declared temp as a method inside the header so that both methods can use it.. I code everything exactly the same for the read method but in the savedata method instead of using plistDict I use temp again. that will now prevent you from loosing your values when the app is removed from multitasking.

    Now in saying all of this you might not see that you are loosing your values depending when you call it / check it.. because if you try to log it when it runs it will always look like its full because if you initialize it before your are able to log it.. the only reason I saw this is because I had a Dictionary inside the dictionary that was only filling one feild at a time.. so I was able to see that 1 out of the 5 values was still there after the relauch of the app after deleting it..

    anyway hope this helps you guys out.. if I’m wrong I would love to hear it.. but I have just spent two days testing and figuring this out :)

  36. xavier says:

    does this data.plist remains when a user deletes the app?? i want to create a lite app and keep user data in this data.plist so when he reaches 3 uses app wont be complete anymore it will be limitated until the user buys the complete app (not the lite one). or how can i manege this??

    • Kent says:

      You can certainly keep a counter in the plist tracking how many times a user uses the app. I’m pretty sure the plist will be deleted with the app, but you could always test that?

  37. Daniel says:

    Thanks I was looking some explanation like this, very helpful and well explain

  38. Samantha says:

    Thank you for this tutorial, It was very useful!

  39. CGS says:

    Hello..
    I downloaded your code…and tried to add the new data and save it..but its not happening…can u please tell me what to do…
    Actually i have a project where i have to just click on button and the label’s text will be added to database…so please help me..
    Thanks in advance

  40. shubh says:

    gr8 example…but after adding new record it will not showing in plist file..whats the problem???

  41. shubh says:

    If we want to see added record then whats the procedure????

  42. mustafa says:

    That’s a useful tutorial. Thanks Kent. I usually prefer to XML instead of Plist. I think it’s more practicable than Plist.

  43. vinoth says:

    sir , i run that application two times my old data was lost . where is my old data

  44. vinoth says:

    i am stop my work and got tension from one week plz reply

  45. Rod says:

    Hi Kent, I have a rootViewController with a pickerView that pushes over 100 separate
    viewControllers (let’s say fruits). I am trying to figure out how to use your tutorial for users to save their favorite fruits to populate a tableView for use at app launch. Should the code be located in the rootViewController, appDelegate etc. Thanks!

  46. Taylor says:

    Thanks a lot for putting your solutions on the web. Your tutorials (including this one) have never failed me. Well done!

  47. Sadiq Amin says:

    how to load this data into table view means i want to display this data from plist to uitableview.please do you have any tutorial?

  48. Bhupendra says:

    kent!! i am not able to find the document folder from your give path. I want to inform you that i am using the vmware so is any difference becuase of it ??

    • Victor_Oak says:

      Hey, there’s no difference, and the directory you can see for yourself, put breakpoints on against the first array and take the next step in the debug window, you will see it contains a variable way address your plist

  49. Pier says:

    Perfect. Got me quickly up to speed, thanks so much!

  50. Victor_Oak says:

    thanks, very useful!

  51. Edison says:

    I have some question , if I save the data to plist,
    will the plist appear the saved data using simulator ?

    Following is my code
    I dont understand where is the problem
    THX
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"FlashCard.plist"];
    WordHere = self.dictionary[FCDataSourceDictionaryKeyWord];
    ChineseHere = self.dictionary[FCDataSourceDictionaryKeyChinese];

    NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: WordHere, ChineseHere, nil] forKeys:[NSArray arrayWithObjects: @"Word", @"Chinese", nil]];
    NSString *error;
    // create NSData from dictionary
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

    if(plistData){
    // write plistData to our Data.plist file
    [plistData writeToFile:plistPath atomically:YES];
    NSLog(@”YES”);
    }
    else{
    NSLog(@”Error in saveData: %@”, error);
    }

  52. Alexis says:

    Hi Kent, thanks for this tutorial! I have a couple questions.

    I’ve created a simple app which is essentially like a multiple choice test. There is a table with all the questions, and when you click on the question, the possible answers come up for you to choose the correct one. This list of questions is almost 700 questions and I was thinking of using a plist to store all the questions and answers along with the correct answer.

    So my questions are:
    1) Is this too much data for a plist, should I go about this a different way?
    2) This data is the apps main data, so I never want it to be deleted. How or where can I save this plist such that it is always there as part of the app? Ie, when the app gets deleted from the iphone or simulator and I re-run it, I want all my data to still be there.

    Thanks for your time and help!

  53. radhakrishna says:

    Were can i see the ..save date ?

  54. Andy says:

    Hi Kent. Thanks for the tutorial. it helped a lot.
    But i got an issue after implementation of save/read data mechanism in my application.
    I can create a file, save data from app’s array, read selected file and load all data to according arrays. But after populating arrays with loaded data the application crashes on every attempt of accessing to any updated array.
    any thoughts on this issue? what could change inside of my arrays?
    Thanks in advance.

  55. Ankit says:

    hi kent ,
    i create new project of plist same as your project. but i get error
    Error reading plist: stream had too few bytes, format: 17612322
    whats wrong in it. plz reply soon

  56. Bob says:

    Now what if you were doing a registration form. How would you retrieve the data for the log in?

  57. ahmet says:

    hi there it is excellent tutorial. thanx for that. i wrote the codes and work perfectly. But it changes the values of data in plist file. is that a way to add more records to same plist? i want to add more names and phones. is there a way?

  58. unnamed says:

    You just saved me! :D thank you!

Add Comment Register



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>