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
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
I just found this tool, you might find it helpful :)
How to use it:
http://api.wunderground.com/api/YOUR_API_KEY/forecast/q/Chicago.json