Reputation: 386
Receiving the following error. I believe it has to do with the NSDictionary in the results of JSON array. I.e. NSDictionary within an NSDictionary maybe?
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x7f9298554560'
This is the JSON service when called. This is printed directly out of XCode but it looks clean to me.
Printing description of self->metArray:
{
weatherObservation = {
ICAO = YBBN;
clouds = "few clouds";
cloudsCode = FEW;
countryCode = AU;
datetime = "2014-11-24 03:00:00";
dewPoint = 20;
elevation = 5;
hectoPascAltimeter = 1014;
humidity = 61;
lat = "-27.38333333333333";
lng = "153.1333333333333";
observation = "YBBN 240300Z 02019KT 9999 FEW029 SCT250 28/20 Q1014";
stationName = "Brisbane Airport M. O";
temperature = 28;
weatherCondition = "n/a";
windDirection = 20;
windSpeed = 19;
};
}
This is the code that invokes the JSON service.
-(void)getMetar{
// NSString *location = @"YBBN";
NSString * const metarUrl =@"http://api.geonames.org/weatherIcaoJSON?ICAO=YBBN&username=demo";
NSURL *url2 = [NSURL URLWithString:metarUrl];
NSData *data2 = [NSData dataWithContentsOfURL:url2];
metArray = [NSJSONSerialization JSONObjectWithData:data2 options:kNilOptions error:nil];
//Create an NSDictionary for the weather data to be stored.
NSDictionary *metarJson = [NSJSONSerialization JSONObjectWithData:data2 options:kNilOptions error:nil];
//Loop through the JSON array
NSArray *currentMetarArray = metarJson[@"weatherObservation"];
//set up array and json call
metarArray = [[NSMutableArray alloc]init];
for (NSDictionary *metaritem in currentMetarArray)
{
//create our object
NSString *nClouds = [metaritem objectForKey:@"clouds"];
NSString *nObservation = [metaritem objectForKey:@"observation"];
//Add the object to our animal array
[metarArray addObject:[[metar alloc]initWithclouds:(nClouds) andobservation:nObservation]];
}
}
It looks okay to me but maybe that is because I have been looking at it for hours.
Any ideas?
Upvotes: 1
Views: 338
Reputation: 5061
The error thrown is the best clue for how you can fix this.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x7f9298554560'
What this means is that you're thinking an object is a dictionary when in reality it isn't.
You can combat this using NSObject methods such as:
[myObject respondsToSelector:(@selector(objectForKey:))]; // will return a boolean value.
to see if the object will respond to the method you hope to send it
or
[myObject isKindOfClass:[NSDictionary class]]; // will return a boolean value.
to determine if the object is a NSDictionary.
What's likely happening, though, is that you have an error in expectation with the Deserialized JSON Data.
Happy bug hunting!
Upvotes: 0
Reputation: 3766
NSArray *currentMetarArray = metarJson[@"weatherObservation"];
for (NSDictionary *metaritem in currentMetarArray)
These lines are wrong. currentMetarArray is a dictionary, not array, it contains string key & value, so you should access it like in following way-
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; NSDictionary *weatherObservation = [jsonDictionary objectForKey:@"weatherObservation"];
then to get nCloud, use like NSString *nClouds = [weatherObservation objectForKey:@"clouds"];
Upvotes: 2
Reputation: 665
I go to your URL and get this message {"status":{"message":"the daily limit of 30000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application.","value":18}}
But you can try my code, it worked for me
NSString *strUrl = @"http://api.geonames.org/weatherIcaoJSON?ICAO=YBBN&username=demo";
NSURL *url = [NSURL URLWithString:strUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSDictionary *weatherObservation = [json objectForKey:@"status"];
for (id key in weatherObservation) {
id value = [weatherObservation objectForKey:key];
NSLog(@"key = %@, value = %@", key, value);
}
Upvotes: 1