I want to programatically create a dictionary which feeds data to my UITableView but I\'m having a hard time with it. I want to create a dictionary that resembles this property
NSMutableDictionary *topLevel = [NSMutableDictionary dictionary];
NSMutableDictionary *item1 = [NSMutableDictionary dictionary];
NSString *item1title = [NSString stringWithString:@"Title 1"];
NSMutableDictionary *item1children = [NSMutableDictionary dictionary];
// create children
NSString *item1child1 = [NSString stringWithString:@"item 1, child 1"];
NSMutableDictionary *item1child2 = [NSMutableDictionary dictionary];
NSString *item1child2title = [NSString stringWithString:@"Title 1-2"];
NSMutableDictionary *item1child2children = [NSMutableDictionary dictionary];
NSString *item1child2child1 = [NSString stringWithString:@"item 1, child 2, child 1"];
NSString *item1child2child2 = [NSString stringWithString:@"item 1, child 2, child 2"];
[item1child2 setObject:item1child2title forKey:@"Title"];
[item1child2children setObject:item1child2child1 forKey:@"item 1 child2 child 1"];
[item1child2children setObject:item1child2child2 forKey:@"item 1 child2 child 2"];
[item1child2 setObject:item1child2children forKey:@"children"];
// add children to dictionary
[item1children setObject:item1child1 forKey:@"item1 child1"];
[item1children setObject:item1child2 forKey:@"item1 child2"];
// add to item 1 dict
[item1 setObject:item1title forKey:@"Title"];
[item1 setObject:item1children forKey:@"children"];
NSMutableDictionary *item2 = [NSMutableDictionary dictionary];
NSString *item2title = [NSString stringWithString:@"Title"];
NSMutableDictionary *item2children = [NSMutableDictionary dictionary];
NSString *item2child1 = [NSString stringWithString:@"item 2, child 1"];
NSString *item2child2 = [NSString stringWithString:@"item 2, child 2"];
NSString *item2child3 = [NSString stringWithString:@"item 2, child 3"];
// add children to dictionary
[item2children setObject:item2child1 forKey:@"item2 child1"];
[item2children setObject:item2child2 forKey:@"item2 child2"];
[item2children setObject:item2child3 forKey:@"item2 child3"];
// add to item 2 dict
[item2 setObject:item2title forKey:@"Title"];
[item2 setObject:item2children forKey:@"children"];
[topLevel setObject:item1 forKey:@"Item 1"];
[topLevel setObject:item2 forKey:@"Item 2"];
first of .. super! thanks .. I really appreciate the explanation and code snippet. Since you gave me such a good explanation I hope you don't mind me asking a couple more questions.
First, I did as you suggested and this is what I came up with : (I used my original property list instead of the example this time so this is where the drilldown table gets his( or needs to get his ) treestructure).
http://img509.imageshack.us/img509/7523/picture2lsg.png
NSDictionary *root = [NSMutableDictionary dictionary];
NSDictionary *item1 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"VirtuaGym Online"] forKey:[NSArray arrayWithObjects:@"Title"]];
NSDictionary *item2 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"Do the training"] forKey:[NSArray arrayWithObjects:@"Title"]];
NSDictionary *item3 = ...
[root setObject:item1 forKey:@"Item 1"];
[root setObject:item2 forKey:@"Item 2"];
Also did some research and tried something else with some other input..
NSMutableArray *Rows = [NSMutableArray arrayWithCapacity: 1];
for (int i = 0; i < 4; ++i) {
NSMutableArray *theChildren = [NSMutableArray arrayWithCapacity: 1];
[theChildren addObject: [NSString stringWithFormat: @"tester %d", i]];
NSString *aTitle = [NSString stringWithFormat: @"Item %d", i];
NSDictionary *anItem = [NSDictionary dictionaryWithObjectsAndKeys: aTitle, @"Title", theChildren, @"Children"];
[Rows addObject: anItem];
}
NSDictionary *Root = [NSDictionary withObject: Rows andKey: @"Rows"];
I decided to just test both of these however it does what I want. It gives me a EXC_BAD_ACCESS
error.
I was also wondering since I saw you using number in your code snippet, couldn't you also use NSString since that's what the plist uses.. could be totally of here of course
NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil]
forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]];
and third a question is about my possible approach to my app. I have an xml parser which saves certain information in different arrays. I want to use this information for my drilldown UITableviews (infoFirstScreen[] infoSecondScreen[] infoThirdScreen[]). The information provided has to be connected like the tree I showed you above. This is the reason I wanted to build the dictionary in code so I can take the info from my arrays and insert it here. My question do you think my approach is correct, wrong or is there a faster way?
again really appreciate the explanation ;)
This is a situation where "teach a man to fish" is a vastly more helpful approach than "give a man a fish". Once you understand the basic principles and the NSDictionary API, it becomes much easier to craft your own custom solution. Here are a few observations and learning points:
nil
argument.Just to give you a flavor of what creating the dictionary in the linked image might look like in code... (I'm ignoring your chosen variable names and using both different approaches for completeness.)
NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil]
forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]];
NSDictionary *item2 = [NSDictionary dictionaryWithObjectsAndKeys:
@"Screen I", @"Title",
[NSArray arrayWithObject:item1], @"Children",
nil];
...
I am not sure I understand the basic objective here.
It seems like at runtime, you are constructing a deep dictionary with many child nodes. But you are constructing this all with static code... why can you not simply make a plist (like the one you had an image of) and read that into an NSDictionary? Both NSDictionary and NSArray have methods that let you simply read in a file and get a whole filled out object. Then it is WAY easier to edit and to understand. That method is dictionaryWithContentsOfFile
.
If all of the data is truly created at runtime before it is put into the dictionary, then it seems like you would want a very different, recursive, style of code rather than the flat examples given.
Lastly, I personally dislike the dictionaryWithObjects:forKeys:
method in NSDictionary for building a dictionary. If you have to do things that way I greatly prefer the alternate method dictionaryWithObjectsAndKeys:
which does the same thing but keeps the keys with the objects:
NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys:
@"Screen J",
@"Title",
[NSNumber numberWithInt:3],
@"View"];