Lucas Veiga
Lucas Veiga

Reputation: 1795

Adding Array to PLIST

I am trying to add and array to a Root array in my plist:

enter image description here

And is not working. Here's my code:

-(IBAction)addName:(id)sender{
NSArray *arrayValues = [NSArray arrayWithObjects: nameLabel.text, nameDate.text, nameValue.text, nil];
NSString *plistpath = [[NSBundle mainBundle] pathForResource:@"Names" ofType:@"plist"];
NSMutableArray *namesNew = [[NSMutableArray alloc] initWithContentsOfFile:plistpath];
[namesNew addObject:arrayValues];   
[namesNew writeToFile:plistpath atomically:YES];
}

What am I doing wrong? Thanks!

Upvotes: 0

Views: 2457

Answers (3)

lakshmen
lakshmen

Reputation: 29064

You need to move the file to NSDocumentDirectory. Then edit the plist file.

For example:

Moving to NSDocumentDirectory:

-(NSDictionary *)copyBundleToDocuments
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [documentPaths objectAtIndex:0];
    NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:@"Names.plist"];
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *bundlePlistPath = [bundlePath stringByAppendingPathComponent:@"Names.plist"];

    //if file exists in the documents directory, get it
    if([fileManager fileExistsAtPath:documentPlistPath])
    {
        NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
        return documentDict;
    }
    //if file does not exist, create it from existing plist
    else
    {
        NSError *error;
        BOOL success = [fileManager copyItemAtPath:bundlePlistPath toPath:documentPlistPath error:&error];
        if (success) {
            NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
            return documentDict;
        }
        return nil;
    }
}

Then get the plist:

 -(void)plistArray:(NSArray*)array
    {
         //get the documents directory:
        NSArray *paths = NSSearchPathForDirectoriesInDomains
        (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];

        //getting the plist file name:
        NSString *plistName = [NSString stringWithFormat:@"%@/Names.plist",
                               documentsDirectory];

         NSMutableArray *namesNew  = [[NSMutableArray alloc] initWithContentsOfFile:plistName];

         [namesNew addObject:arrayValues];

         [namesNew writeToFile:plistName atomically:YES];

         return nil;
    }

Upvotes: 1

SpaceDust__
SpaceDust__

Reputation: 4914

You cant write your plist to the bundle you need to use NSDocumentDirectory or NSCachesDirectory

Just copy your plist to bundle the overwrite it.

Note: learn the difference between NSCachesDirectory and NSDocumentDirectory https://developer.apple.com/icloud/documentation/data-storage/

Copy your plist from bundle to documents(in below code caches), you need to this only one time if your plist in your bundle, I prefer using this code in appdelegate.m when - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Names.plist"];
    NSString *plistInDocuments=@"Names.plist";

    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:plistInDocuments];

    NSError *error = nil;
    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
        [[NSFileManager defaultManager] copyItemAtPath:sourcePath
                                                toPath:dataPath
                                                 error:&error];
    }
    NSLog(@"Error description-%@ \n", [error localizedDescription]);
    NSLog(@"Error reason-%@", [error localizedFailureReason]);

Get your file and overwrite it

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *plistInDocuments=@"Names.plist";
        NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:plistInDocuments];

        //add object here
        NSMutableArray *namesNew = [[NSMutableArray alloc] initWithContentsOfFile:dataPath];
[namesNew addObject:arrayValues];

        NSError *error = nil;
        if ([myFile writeToFile:dataPath options:NSDataWritingAtomic error:&error]) {
            // file saved
        } else {
            // error writing file
            NSLog(@"Unable to write plist to %@. Error: %@", dataPath, error);
        }

Upvotes: 0

Cory Powers
Cory Powers

Reputation: 1140

The plist should be a dictionary as the base object instead of an array.

NSMutableDictionary *namesNew = [NSMutableDictionary dictionaryWithContentsOfFile:plistpath];
[namesNew setObject: arrayValues forKey: @"Root"];
[namesNew writeToFile:plistpath atomically:YES];

Upvotes: 0

Related Questions