Friday, September 27, 2013

Data Persistence using PLIST

Data Persistence using PLIST

I was working on an app a few months ago in which I needed data persistence.  I hadn’t yet mastered Core Data so I found that I could use property lists to store the data.  After some reading and lots of google searches, I found that the following solution worked for me.
This post assumes you already know your way around Xcode and basic iOS programming.  This was programmed in Xcode version 4.6 for iOS5.

The Data

Here is what the data looks like in the UITableViews:


The UITableView contains restaurants, corresponding dishes and ratings  I decided to store the data in the following format:

I made a NSMutableArray of NSMutableDictionaries which contains the restaurant name and a NSMutableArray of dishes from the restaurant.  This dish array is made up of NSMutableDictionaries that contain the dish name and dish rating. This diagram might help clarify:

Plists can store data in arrays and dictionaries, so in this way I did not have to convert the data format.  I simply included a plist file in the app’s Supporting Files directory, then in ViewDidLoad of my master view controller I copied the contents of the file into an array.  Then modified the dictionary values within the array when the user added or deleted an item and saved it back into the file when the app exit.

Creating Plist file

To create a plist file in XCode, go to File->New->Resources->Plist, save the file in the supporting files directory.  You can then modify the plist file and add the data you would like to use in your app.  In my case the plist file looked something like this:

Loading Plist values

With the .plist file under the supporting files folder, I read in the file in the MasterViewController file in the viewDidLoad method.

//search documents directory
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
plistPath = [rootPath stringByAppendingPathComponent:@"restaurants.plist"];

//check resource directory
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
       plistPath = [[NSBundle mainBundle] pathForResource:@"restaurants" ofType:@"plist"];
//load array
self.restaurantArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];

(Code referenced from here)

Saving Plist values

After adding data to my restaurant and dish dictionaries, I call this function to save the data into the documents folder.

   NSString *rootPath1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
   NSString *plistPath1 = [rootPath1 stringByAppendingPathComponent:@"restaurants.plist"];
   [self.restaurantArray writeToFile:plistPath1 atomically:YES];

(Code referenced from here)

With this I was able to load, add, modify and save data to my plist.  Modifying the data consisted of adding objects into arrays and dictionaries where needed.
Of course there are other ways of doing this, but I found this way worked for me till the next release of the app in which I used Core Data instead.

Reference Links

Plist reference

Code reference