Question

How can I append values to an existing key in NSDictionary from a plist?

What I have is basically a plist saved in disc with a few keys and values, the keys are the names of some students with one initial value. What I’m trying to do that doesn't work is to append more items to existing keys/Students by reading the plist, adding it to a temporary NSDictionary, appending a temporary array to an existing key in the plist but when I save the plist back it doesn’t work, it only saves the last two items and basically deletes the initial value for that key.

Here is the code that I’m using…

- (IBAction)testing:(id)sender
{
    NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [dirPaths objectAtIndex:0];
    NSString *fullPath = [documentsPath stringByAppendingPathComponent:@"studentsRecords.plist"];

    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:fullPath];

    if(fileExists)
    {
        NSMutableDictionary *dictionaryRecords = [[NSMutableDictionary alloc]initWithContentsOfFile:fullPath];
        NSLog(@"Items for Nathan: %@",[dictionaryRecords objectForKey:@"Nathan"]);// here the output is, Items for Nathan: Ruler
        // which make sense since I only had one initial record for Nathan in my plist,

        // Here, I want to add two more items to the key Nathan by appending an arry to
        // NSMutableDictionary (dictionaryRecords) but it doesnt work
        NSArray *tempArray = @[@"NoteBook", @"Pencil"];
        [dictionaryRecords setObject:tempArray forKey:@"Nathan"];

        [dictionaryRecords writeToFile:fullPath atomically:YES];
        // when I check the plist after saving this, I only see the last two values, NoteBook and Pencil
        // instead of the three that I'm expecting, Ruler, NoteBook and Pencil
    }

}

What am I missing here?

Thanks a lot in advance.

Was it helpful?

Solution

[dictionaryRecords setObject:tempArray forKey:@"Nathan"] replaces whatever the previous value was with tempArray.

If you want to add to the existing array, you have to retrieve it, make a mutable copy, and append to it.

OTHER TIPS

Here is how I made it work. I hope I didn't over complicated things here but for some reason I had to use two arrays, an NSArray and an NSMutableArray, I would think that the NSMutableArray would be enough but it didn't work.

- (IBAction)testing:(id)sender
{
    // get directory path
    NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [dirPaths objectAtIndex:0];
    // create plist
    NSString *fullPath = [documentsPath stringByAppendingPathComponent:@"studentsRecords.plist"];

    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:fullPath];

    // if file exists create dictionary
    if(fileExists)
    {
        // add items from plist to dictionary
        NSDictionary *dictionaryExistingRecords = [[NSDictionary alloc]initWithContentsOfFile:fullPath];
        // make a copy if dictinary with existing items
        NSMutableDictionary *dictionaryNewRecords = [dictionaryExistingRecords mutableCopy];
        // array to hold existing values from a spcecified key
        NSArray *arrayWithExistingKey = [dictionaryExistingRecords objectForKey:@"Nathan"];
        // mutable array to add existing and be able to insert new items
        NSMutableArray *arrayOldAndNewItems = [NSMutableArray arrayWithArray:arrayWithExistingKey];
        // insert new items to array
        [arrayOldAndNewItems addObject:@"Snow Pans"];
        // add old and new items to specified key
        [dictionaryNewRecords setObject:arrayOldAndNewItems forKey:@"Nathan"];
        // save new records to plist
        [dictionaryNewRecords writeToFile:fullPath atomically:YES];
    }
}
@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top