Adding dictionaries to Plist programmatically

2019-09-09 19:42发布

问题:

I am trying to add a dictionary to a plist programmatically in the following format:

Root(Dict) | StringOfViewID(Dict) | ButtonTitle(Dict) | String String

I can successfully do this but I want to keep adding to the ViewID(Dict) more ButtonTitle(Dict) under the same ViewID(Dict).

So far I can only replace the existing.

Something like this:

Root(Dict) | StringOfViewID(Dict) - ButtonTitle(Dict)(2)-String String | ButtonTitle(Dict)(1) | String String

Here is the code I'm using:

//Initialize and load the plist file here: 
[...]
            NSMutableDictionary *data;
            NSMutableDictionary *viewID;
            NSMutableDictionary *buttonName;
            NSArray *keys;
            NSArray *locations;


        // Insert the data into the plist

        NSNumber *xNumber = [[NSNumber alloc] initWithDouble:locationX];
        NSNumber *yNumber = [[NSNumber alloc] initWithDouble:locationY];

        keys = [NSArray arrayWithObjects:@"locationX", @"locationY", nil];
        locations = [NSArray arrayWithObjects:xNumber, yNumber, nil];
        data = [NSMutableDictionary dictionaryWithObjects:locations forKeys:keys];
        buttonName = [NSMutableDictionary dictionaryWithObject:data forKey:myButtonTitle];
        viewID = [NSMutableDictionary dictionaryWithObject:buttonName forKey:@"StringOfViewID"];

        [viewID writeToFile:path atomically:YES];

Thanks

回答1:

I would create a class to serve as a data model. This is a simple implementation - it would probably be cleaner to create a Button object rather than pass multiple parameters and retrieve a dictionary

ViewButtons.h

@interface ViewButtons : NSObject

+(ViewButtons *) viewButtonsWithContentsOfFile:(NSString *)file;

-(void) addButton:(NSString *)buttonName withX:(double) x andY:(double) y toView:(NSString *)viewName;
-(NSArray *)viewNames;
-(NSArray *)buttonNamesForView:(NSString *)viewName;
-(NSDictionary *)buttonWithName:(NSString *)name inView:(NSString *)viewName;
-(void)writeToFile:(NSString *)file;

@end

ViewButtons.m

#import "ViewButtons.h"

@interface ViewButtons ()

@property (nonatomic,strong) NSMutableDictionary *viewButtons;

@end

@implementation ViewButtons

-(id) init {
    if (self=[super init]) {
        self.viewButtons=[NSMutableDictionary new];
    }
    return self;
}

+(ViewButtons *) viewButtonsWithContentsOfFile:(NSString *)file {
    ViewButtons *newViewButtons=[ViewButtons alloc];
    newViewButtons.viewButtons=[NSMutableDictionary dictionaryWithContentsOfFile:file];
    return newViewButtons;
}

-(void) addButton:(NSString *)buttonName withX:(double) x andY:(double) y toView:(NSString *)viewName {
    NSMutableDictionary *viewDict=self.viewButtons[viewName];
    if (viewDict == nil) {
        viewDict=[NSMutableDictionary new];
        self.viewButtons[viewName]=viewDict;
    } else if (![viewDict isKindOfClass:[NSMutableDictionary class]]) {
        viewDict=[viewDict mutableCopy];
        self.viewButtons[viewName]=viewDict;
    }
    NSNumber *xNumber = [NSNumber numberWithDouble:x];
    NSNumber *yNumber = [NSNumber numberWithDouble:y];
    NSDictionary *buttonDict=@{@"locationX":xNumber,@"locationY":yNumber};
    viewDict[buttonName]=buttonDict;
}


-(NSArray *)viewNames {
    return self.viewButtons.allKeys;
}

-(NSArray *)buttonNamesForView:(NSString *)viewName {
    return [self.viewButtons[viewName] allKeys];
}
-(NSDictionary *)buttonWithName:(NSString *)name inView:(NSString *)viewName {
    return self.viewButtons[viewName][name];
}

-(void)writeToFile:(NSString *)file {
    [self.viewButtons writeToFile:file atomically:YES];
}

@end

You can use this class as follows -

ViewButtons *viewButtons=[ViewButtons viewButtonsWithContentsOfFile:buttonFile];
if (viewButtons == nil) {
    viewButtons=[ViewButtons new];
}

[viewButtons addButton:@"MyButton1" withX:0 andY:0 toView:@"MyView"];
[viewButtons addButton:@"MyButton2" withX:1 andY:1 toView:@"MyView"];
[viewButtons addButton:@"MyButton3" withX:0 andY:0 toView:@"MySecondView"];
[viewButtons addButton:@"MyButton4" withX:0 andY:1 toView:@"MyThirdView"];
[viewButtons writeToFile:buttonFile];


回答2:

Simply load the file first into NSMutableDictionary , make the changes you want to it, then write it back to the file using the same code you use already.

Edit: Regarding the structure you use for editing the list , you can either have an array of button dictionaries

   NSMutableDictionary* oldDictionary=[NSMutableDictionary dictionaryWithContentsOfFile:path];

   // make the new button dictionary
   NSNumber *xNumber = [[NSNumber alloc] initWithDouble:locationX];
   NSNumber *yNumber = [[NSNumber alloc] initWithDouble:locationY];

   NSDictionary*buttonDictionary=@{@"locationX": xNumber,
                                   @"locationY":yNumber,
                                   @"myButtonTitle":myButtonTitle};
   NSMutableArray *buttonsArray = [oldDictionary objectForKey:@"StringOfViewID"];
   //append it to the array
   [buttonsArray addObject:buttonDictionary];
   //replace the old array with the new one
   [oldDictionary setObject:buttonsArray forKey:@"StringOfViewID"];
   //write it back to the file
   [oldDictionary writeToFile:path atomically:YES];

Or a dictionary of buttons dictionaries

    NSMutableDictionary* oldDictionary=[NSMutableDictionary dictionaryWithContentsOfFile:path];

    // make the new button dictionary
    NSNumber *xNumber = [[NSNumber alloc] initWithDouble:locationX];
    NSNumber *yNumber = [[NSNumber alloc] initWithDouble:locationY];

    NSDictionary*buttonLocationDictionary=@{@"locationX": xNumber, @"locationY":yNumber};
    NSMutableDictionary *buttonsDictionary = [oldDictionary objectForKey:@"StringOfViewID"];
    //add it to the dictionary
    [buttonsDictionary  setObject:buttonLocationDictionary forKey:myButtonTitle];//be sure that this is a new button title,or else it will replace the old value with this title.

    //replace the old dictionary with the new one
    [oldDictionary setObject:buttonsDictionary forKey:@"StringOfViewID"];
    //write it back to the file
    [oldDictionary writeToFile:path atomically:YES];

I tried to not change the structure or the keys you are using, and I assumed that StringOfViewID is the key that all the buttons in the current view of interest will have, and other views will have other keys.