How to write a data in plist?
Asked Answered
O

1

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.

Organicism answered 2/10, 2011 at 18:32 Comment(0)
B
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];
Baldwin answered 2/10, 2011 at 18:38 Comment(8)
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.Organicism
I've added an example to my answer. :)Baldwin
@Colas Why? You only need to create your own instance if you want to use a delegate, as explained here: https://mcmap.net/q/672217/-are-there-any-cases-where-it-39-s-better-to-use-nsfilemanager-defaultmanager-rather-than-nsfilemanager-alloc-init and in the docs: developer.apple.com/library/prerelease/ios/documentation/Cocoa/…Baldwin
[[NSFileManager alloc] init] is supposed to be better, regarding the management of threads.Thunderstone
would you ever write the plist back to the application bundle?Armbrecht
@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 ?Equi
@PulkitSharma You should ask this as a separate question.Baldwin
@chrisklaussner Already did pal. #35378205Equi

© 2022 - 2024 — McMap. All rights reserved.