Search code examples
iosjsonsbjson

SBJson displays null


I am trying to parse some json data with SBJson to show the current temperature. The example code from this tutorial works perfect: Tutorial: Fetch and parse JSON

When I change the code to my json feed i get a null. I am kind of new to JSON but followed every tutorial and documentation I found. The json source i used: JSON Source

My code with sbjson:

NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;

NSArray* currentw = [(NSDictionary*)[responseString JSONValue] objectForKey:@"current_weather"];

//choose a random loan
NSDictionary* weathernow = [currentw objectAtIndex:0];

//fetch the data
NSNumber* tempc = [weathernow objectForKey:@"temp_C"];
NSNumber* weatherCode = [weathernow objectForKey:@"weatherCode"];


NSLog(@"%@ %@", tempc, weatherCode);

and of course I have already implemented the other sbjson code.


Solution

  • There is no current_weather key in the JSON data you posted. The structure is:

    { "data": { "current_condition": [ { ..., "temp_C": "7", ... } ], ... } }
    

    Here's a visual representation:

    JSON visual representation

    Therefore, to get to temp_C, you'd need to first obtain the top-level data property:

    NSDictionary* json = (NSDictionary*)[responseString JSONValue];
    NSDictionary* data = [json objectForKey:@"data"];
    

    then, from that, obtain the current_location property:

    NSArray* current_condition = [data objectForKey:@"current_condition"];
    

    and finally, from the current_location array, get the element you're interested in:

    NSDictionary* weathernow = [current_condition objectAtIndex:0];
    

    Also note that temp_C and weatherCode are strings, not numbers. To transform them to numbers, instead of:

    NSNumber* tempc = [weathernow objectForKey:@"temp_C"];
    NSNumber* weatherCode = [weathernow objectForKey:@"weatherCode"];
    

    you could use something like:

    int tempc = [[weathernow objectForKey:@"temp_C"] intValue];
    int weatherCode = [[weathernow objectForKey:@"weatherCode"] intValue];
    

    (or floatValue / doubleValue if the value is not supposed to be an int, but rather a float or a double)

    You would then use %d (or %f for float / double) as a format string:

    NSLog(@"%d %d", tempc, weatherCode);