0

Im working with flickr and in the sample fetch I get this:

{
    "api_key" =     {
        "_content" = 3c6eeeae4711a5f478d3da796750e06b;
    };
    format =     {
        "_content" = json;
    };
    method =     {
        "_content" = "flickr.test.echo";
    };
    nojsoncallback =     {
        "_content" = 1;
    };
    stat = ok;
}

This is a dictionary with 5 entries (api_key, format, method, nojsoncallback & stat). The first 4 entires are dictionaries themselves.

First off, there is a 5th element in my original dictionary, which is not a dictionary, it is simply the last entry in the original dictionary (the one stat=ok). Furthermore, I want the _content key in every subentry to appear in my individual cells but I dont want to hardcode any values. Do I HAVE to setup an array?

marciokoko
  • 4,988
  • 8
  • 51
  • 91
  • 1
    What have you tried? This is a totally straightforward use of NSDictionary. You know the structure and you know all the keys. – matt Apr 16 '13 at 02:43
  • A loop comes to mind. (Maybe, though, you'll actually have to look at the NSDictionary documentation.) – Hot Licks Apr 16 '13 at 03:20
  • Yes but I want to write a loop that gets every objectForKey without knowing the key names. – marciokoko Apr 16 '13 at 03:29
  • It would have been nice if you'd mentioned that when you originally posed your question. – matt Apr 16 '13 at 04:30
  • Could you say more about what sort of results you'd like to have? I mean, you've already got the dictionaries themselves; they *are* key-value pairs. So what would you like to have instead? "Gets every objectForKey without knowing they key names" - you mean you just want results like `[3c6eeeae4711a5f478d3da796750e06b, json, flickr.test.echo, 1]`? Or what? – matt Apr 16 '13 at 04:33
  • Quite similar, perhaps, to this? http://stackoverflow.com/questions/8268366/how-to-get-values-without-using-key-from-nsdictionary-nsmutabledictionary-in-iph?rq=1 – matt Apr 16 '13 at 04:35
  • @matt thanks but I think im asking a slightly different question. First off, there is a 5th element in my original dictionary, which is not a dictionary, it is simply the last entry in the original dictionary (the one stat=ok). Furthermore, So I want the _content key in every subentry to appear in my individual cells but I dont want to hardcode any values. Do I **HAVE** to setup an array? – marciokoko Apr 16 '13 at 14:33
  • Like I said, reading the documentation might help. – Hot Licks Apr 16 '13 at 15:16
  • You could just use the array of dictionaries you've been given as the "model" for the table data, and fetch out the desired value in `cellForRowAtIndexPath:`. The problem is that a dictionary has no order! So which is the value for the *first* row of the table? Which is the value for *second* row of the table? You don't have any determinate way of answering that question. – matt Apr 16 '13 at 15:31
  • So for that reason I would need a sorted nsarray? – marciokoko Apr 16 '13 at 16:18
  • It doesn't need to be sorted. But at least an array has an order. A dictionary does not. An array is a good model for a table view because it has indexes (myArray[0], myArray[1], and so on) which can correspond to the rows of a table (row 0, row 1, and so on). For this reason, people often like to set up their table model data as an array: it gives a determinate, rapid way of accessing the correct piece of data, as I discuss in my book: http://www.apeth.com/iOSBook/ch21.html#_the_three_big_questions – matt Apr 16 '13 at 18:00

2 Answers2

4

NSDictionary has a nifty little method called valueForKeyPath. Thats your savior here.

[dict valueForKeyPath:@"api_key._content"]
[dict valueForKeyPath:@"format._content"]
[dict valueForKeyPath:@"method._content"]
[dict valueForKeyPath:@"nojsoncallback._content"]

What it does is traverse the key path and fetch the values of content in each JSON substructure. Otherwise you would have had to written a for-loop and loop through it. Neat huh?

Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
  • Thanks, that is quite handy! :) However, I need to get each value separately and put it into a different cell. So basically I would have to create a switch here to put in the right value in the right cell, correct? – marciokoko Apr 16 '13 at 14:25
  • yes if you want to put each value in different cell you might have to put a `if-else` on the `index path` of the `UITableViewCell`. The above mentioned JSON parsing needs to be done at the top level loop. – Srikar Appalaraju Apr 16 '13 at 14:49
  • Ive got this so far...`for (NSString *key in flickrDictionary) { NSLog(@"the key is %@", flickrDictionary[key]); id object = flickrDictionary[key]; // this will be apikey,format,method etc... if ([object isKindOfClass:[NSDictionary class]]) { //first 4 are arrays-crsh-dicts NSLog(@"object valueForKey is %@", [object valueForKey:@"_content"]); cell.textLabel.text = [object valueForKey:@"_content"]; } else { cell.textLabel.text = flickrDictionary[key]; } }` i guess ill just put it into an array – marciokoko Apr 16 '13 at 14:51
2

Try this

for (NSString *key in dictionary){
    id object = dictionary[key];
    if ([object isKindOfClass:[NSDictionary class]]) {
    //Now you can work on the dictionary object
    }
}
Anupdas
  • 10,211
  • 2
  • 35
  • 60
  • Ok I tried your suggestion like so: `for (NSString *key in flickrDictionary) { id object = flickrDictionary[key]; if ([object isKindOfClass:[NSDictionary class]]) { cell.textLabel.text = [object valueForKey:@"_content"]; } }` So Im saying, if the object for the first key(api_key) is a dictionary, which it is, get its _content key and put it into the cell. But I get the api_key in all 5 cells :( Id have to use the indexpath somehow, right? I want the _content key in every subentry to appear in my individual cells but I dont want to hardcode any values. – marciokoko Apr 16 '13 at 14:32