how to add values to a dictionary inside a dictionary of a property list

Go To


I am currently creating a controller class for my this plist I have a root dictionary that has several types in it (Number, String and Dictionary), In my controller class I check for a plist then add it to the documents so I can read and write to it.

From here I read whats in my current plist and pass those values over to tempvars I have set up in this class.

This is what my read method looks like in my plist controller class.

-(void) readPlistData
    // Data.plist code
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"EngineProperties.plist"];

    // check to see if Data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
        // if not in documents, get property list from main bundle
        plistPath = [[NSBundle mainBundle] pathForResource:@"EngineProperties" ofType:@"plist"];

    // read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    // convert static property liost into dictionary object
    NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    if (!temp)
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
    // assign values
    self.protocolSignature = [temp objectForKey:@"Protocol"];
    self.requestNumber = [temp objectForKey:@"RequestNumber"];

    //How do I add the dictionary values here?

The reason I put the data into variables is because latter I am going to use these values to test against checks I want to perform against my db.. making sure of things like i am receiving the correct request number etc.

UPDATE:: my idea to add them to the dictionary inside the root dictionary would be something like this. which i think is not even close but it might give you a better clue to what I am trying to do.

self.cacheValue = [temp objectForKey:@"Cache Value"];
self.manufacturers = [cacheValue objectForKey:@"Manufacturers"];
    self.models = [cacheValue objectForKey:@"Model"];
    self.subModels = [cacheValue objectForKey:@"SubModels"];

any help would be greatly appreciated.

enter image description here

2012-04-04 01:34
by C.Johns
Can you give a basic example of the plist? I'm not really following it in your example. It sounds like you want to use a NSMutableDictionary - rwyland 2012-04-04 01:59
I have updated with a screen shot of my plist as above, as you can see I am trying to figure out how to code the Cache Value dictionary and its sub value - C.Johns 2012-04-04 02:05


I believe you want to do the following:

Define your cacheValue property in the .h as a mutable dictionary.

NSMutableDictionary *cacheValue;

Serialize the plistXml as a NSMutableDictionary:

// This is the root Dictionary
NSMutableDictionary *temp = (NSMutableDictionary *)[NSPropertyListSerialization propertyListWithData:plistXML options:NSPropertyListMutableContainersAndLeaves format:NSPropertyListXMLFormat_v1_0 error:&error];

Since everything is mutable, you can now read, update, insert, delete any part of the dictionary or its subcontents. For instance, grabbing the Mutable Dictionary "Cache Value" is just:

self.cacheValue = [temp objectForKey:@"Cache Value"];

Remember to check that the object is not nil in case there isn't a value for the key. The key needs to be exactly as it appears in the plist.

Updating a value in the Mutable Dictionary is easy:

[self.cache setValue:@"New Value" forKey:@"Sub"];

And finally, to save the changes in the root Mutable Dictionary back to the plist:

 The flag "atomically" specifies whether the file should be written atomically or not.
 If flag is YES, the receiver is written to an auxiliary file, and then the auxiliary file is renamed to path.
 If flag is NO, the dictionary is written directly to path.
 The YES option guarantees that path will not be corrupted even if the system crashes during writing.
[self.temp writeToFile:plistPath atomically:YES];

Hope this helps, cheers!

2012-04-04 02:40
by rwyland
okay thank you I am going to attempt this implementing your solution now. I will let you know how I go : - C.Johns 2012-04-04 03:24
thank you for teaching me about NSPropertyListMutableContainersAndLeaves - Matthias Bauch 2012-04-04 03:29