7

I have followed this answer to write data to the plist

How to write data to the plist?

But so far my plist didn't change at all.

Here is my code :-

- (IBAction)save:(id)sender
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
    NSString *drinkName = self.name.text;
    NSString *drinkIngredients = self.ingredients.text;
    NSString *drinkDirection = self.directions.text;
    NSArray *values = [[NSArray alloc] initWithObjects:drinkDirection, drinkIngredients, drinkName, nil];
    NSArray *keys = [[NSArray alloc] initWithObjects:DIRECTIONS_KEY, INGREDIENTS_KEY, NAME_KEY, nil];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjects:values forKeys:keys];
    [self.drinkArray addObject:dict];
    NSLog(@"%@", self.drinkArray);
    [self.drinkArray writeToFile:path atomically:YES];
}

Do I need to perform something extra?

I am new to iPhone SDK so any help would be appreciated.

Community
  • 1
  • 1
Varundroid
  • 9,135
  • 14
  • 63
  • 93

1 Answers1

36

You are trying to write the file to your application bundle, which is not possible. Save the file to the Documents folder instead.

NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:@"drinks.plist"];

The pathForResource method can only be used for reading the resources that you added to your project in Xcode.

Here's what you typically do when you want to modify a plist in your app:
1. Copy the drinks.plist from your application bundle to the app's Documents folder on first launch (using NSFileManager).
2. Only use the file in the Documents folder when reading/writing.

UPDATE

This is how you would initialize the drinkArray property:

NSString *destPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
destPath = [destPath stringByAppendingPathComponent:@"drinks.plist"];

// If the file doesn't exist in the Documents Folder, copy it.
NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath:destPath]) {
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
    [fileManager copyItemAtPath:sourcePath toPath:destPath error:nil];
}

// Load the Property List.
drinkArray = [[NSArray alloc] initWithContentsOfFile:destPath];
Bejil
  • 412
  • 5
  • 18
klaussner
  • 2,364
  • 3
  • 25
  • 33
  • Thanks a lot for your reply. I am just learning iPhone SDK so can you please tell me how to copy it at first launch. Where should i put the code to copy my .plist to my app bundle? and how would i know that it has been copied successfully? Thanks. – Varundroid Oct 03 '11 at 14:17
  • 3
    I've added an example to my answer. :) – klaussner Oct 03 '11 at 19:45
  • @Colas Why? You only need to create your own instance if you want to use a delegate, as explained here: http://stackoverflow.com/a/16404926/499350 and in the docs: https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html#//apple_ref/occ/clm/NSFileManager/defaultManager – klaussner Jun 23 '15 at 14:22
  • `[[NSFileManager alloc] init]` is supposed to be better, regarding the management of threads. – Colas Jun 25 '15 at 09:39
  • would you ever write the plist back to the application bundle? – Gene Myers Jun 25 '15 at 14:27
  • @chrisklaussner In my app i am required to persist around 800 to 1000 objects each having 4-5 boolean variables (which are editable/ can be modified - very often), so keeping that in mind is using plist a good option for tjis requirement ? – Pulkit Sharma Feb 13 '16 at 14:45
  • @PulkitSharma You should ask this as a separate question. – klaussner Feb 13 '16 at 19:45
  • @chrisklaussner Already did pal. http://stackoverflow.com/questions/35377705/approach-for-small-database-ios – Pulkit Sharma Feb 14 '16 at 13:55