Question

I'm trying to read data from weather underground via their JSON API. I'm able to read conditions data which looks like this:

weatherReturn = { "current_observation" = { UV = 1; "dewpoint_c" = 2; "dewpoint_f" = 35; "dewpoint_string" = "35 F (2 C)"; "display_location" = { city = Chicago; country = US; ...

Now, I'm trying to read JSON data from the forecast data which looks like this:

forecast = { simpleforecast = { forecastday = ( { avehumidity = 45; avewind = { degrees = 141; dir = SE; kph = 14; mph = 9; }; conditions = Clear; date = { ampm = PM; day = 19;

and my code is returning null for the attributes I'm trying to pick up.

Since forecast has more layers to the JSON data than conditions, I'm trying a new method which is returning the nulls. Also, I noticed there is a left paren after forecast_day for the forecast data.

The code I'm trying is below:

urlNSString = [NSString stringWithFormat:@"http://api.wunderground.com/api/%@/forecast/q/Chicago.json",
             kWeatherAPIKey];
NSURL *url          = [NSURL URLWithString:urlNSString];

NSData *weatherCall = [NSData dataWithContentsOfURL:url];    

id weatherReturn = [NSJSONSerialization weatherCall options:0 error:&error];

NSMutableDictionary *response = [[[weatherReturn valueForKey:@"forecast"] objectAtIndex:0]mutableCopy];
NSString *parma = [response valueForKey:@"avehumidity"];
NSString *parmb = [response valueForKey:@"pretty"];
NSString *parmc = [response valueForKey:@"ampm"];

NSLog(@"parms are %@%@%@",parma,parmb,parmc);

When I run with this code I get this error on the NSMutableDictionary statement: [__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x9847fa0 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x9847fa0'

libc++abi.dylib: terminating with uncaught exception of type NSException

Was it helpful?

Solution

The response is not a simple NSDictionary object. It is a dictionary of arrays and dictionaries that may contain other arrays and dictionaries etc.

You have to know what is the structure of your response (for example by NSLogging it).
Try: NSLog(@"%@", weatherReturn);


{...} means a NSDictionary object.
(...) means a NSArray object

I changed your code to prove that the params you're looking for are not nil.

- (void)viewDidLoad
{
    [super viewDidLoad];


    NSString *urlNSString = [NSString stringWithFormat:@"http://api.wunderground.com/api/%@/forecast/q/Chicago.json",kWeatherAPIKey];
    NSURL *url          = [NSURL URLWithString:urlNSString];

    NSData *weatherCall = [NSData dataWithContentsOfURL:url];

    NSError *error;
    id weatherReturn = [NSJSONSerialization JSONObjectWithData:weatherCall options:0 error:&error];

    NSLog(@"%@", weatherReturn);

    id forecast = [weatherReturn valueForKey:@"forecast"];
    id simpleforecast = [forecast valueForKey:@"simpleforecast"];
    id forecastday = [simpleforecast valueForKey:@"forecastday"];

    id firstPartOfDailyForecast = [forecastday firstObject];

    id avehumidity = [firstPartOfDailyForecast valueForKey:@"avehumidity"];

    id date = [firstPartOfDailyForecast valueForKey:@"date"];

    id pretty = [date valueForKey:@"pretty"];
    id ampm = [date valueForKey:@"ampm"];


    NSLog(@"Ave:%@\nPretty:%@\nAM/PM:%@", avehumidity, pretty, ampm);
}

IMPORTANT
I'm not calling valueForKey: method on weatherReturn all the time, but i'm getting deeper and deeper inside the response structure.


This is how the structure looks like for param with key "ampm"

--NSDictionary (response)
----NSDictionary for key forecast
-------NSDictionary for key simpleforecast
---------NSArray for key forecastday
-----------NSDictionary as first array object
-------------NSDictionary for key date
---------------NSString for key ampm

EDIT:

I just found this tool, you might find it helpful :)

JSON VIEWER

How to use it:

  1. Place your request (but change API KEY :)) request into a browser
    http://api.wunderground.com/api/YOUR_API_KEY/forecast/q/Chicago.json
  2. Copy the API response to the tool's 'Text' page.
  3. Go to 'Viewer' page and analize the response.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top