SIGABRT on NSDictionary objectAtIndex: unrecognized selector - objective-c

I'm having a weird error here.
I have an array named __ImageData:
static NSArray *__ImageData = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:#"ImageData" ofType:#"plist"];
NSData *plistData = [NSData dataWithContentsOfFile:path];
NSString *error; NSPropertyListFormat format;
_ImageData = [NSPropertyListSerialization propertyListFromData:plistData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&error];
When I NSLog out the content of the array, I get this output:
2012-08-23 16:36:35.573 CAT[28814:c07] {
"Item 0" = {
height = 7121;
name = Map1;
width = 8556;
};
"Item 1" = {
height = 7121;
name = Map2;
width = 8556;
};
"Item 2" = {
height = 7121;
name = Map3;
width = 8556;
};
}
But when I NSLog out NSLog(#"%#", [__ImageData objectAtIndex:0]);, I get this exception:
2012-08-23 16:36:35.573 CAT[28814:c07] -[__NSCFDictionary objectAtIndex:]:
unrecognized selector sent to instance 0x719d0f0
2012-08-23 16:36:35.574 CAT[28814:c07] *** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]:
unrecognized selector sent to instance 0x719d0f0'
*** First throw call stack:
etc..
I have no idea how to reach an object in this array.. It seemes like the objectAtIndex cant find any indexes, not even index:0, even though there is data inside.. Anyone know how to get it?
I am using the PhotoScroller-template from Apple, using the CATiledLayer. I think the whole thing is kinda funky, but everybody says we should use this for large images. Anyone have an explanation or a better idea than CATiledLayer for huge images? (8556*7121px).
And why do I get Dictionary-error from the NSArray?
When doing NSDictionary *dict = [__ImageData objectAtIndex:0], I also get the same exception.
Stian.

_ImageData is not an array, it is a dictionary. To display the first element of the dictionary you could do something like:
NSLog(#"%#", [_ImageData objectForKey:#"Item 0"]);

I ran into this same issue using an JSON Array. My fix was to convert it to an NSDictionary like so:
[(NSDictionary *)json objectForKey:#"detail"];
Or you could do it like this:
NSDictionary *dict = (NSDictionary *)array;

Related

JSON ObjectiveC - Error

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?
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"];
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);
}
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!

How to parse this JSON response into a key & value pairs array

there are a lot of questions like this and i'm experienced with json format too but i couldnt parse the response below(at the bottom):
I'm using NSJSONSerialization for parsing the response into NSDictionary but the it gives the error like below:
My code:
NSString *subURL= sharedDa.ip;
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.69.230/tsadmin.php?tssearch=%#", subURL]]];
NSError *error=nil;
NSDictionary* portsResult=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers error:&error];
NSDictionary * tempPorts;
NSString *k;
for(k in [portsResult allKeys]){
tempPorts = [portsResult objectForKey:k];
NSLog(#"Temporary ports: %#", tempPorts);
}
And the error code is below:
2012-09-28 18:47:37.508 BNTPRO ST Manager[2609:fb03] -[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0
2012-09-28 18:47:37.511 BNTPRO ST Manager[2609:fb03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0'
*** First throw call stack:
(0x1568022 0x1b20cd6 0x1569cbd 0x14ceed0 0x14cecb2 0x57cd 0x28fa1e 0x28fd11 0x2a18fd 0x2a1aef 0x2a1dbb 0x2a285f 0x2a2e06 0x2a2a24 0x3e59 0x2595c5 0x2597fa 0xaee85d 0x153c936 0x153c3d7 0x149f790 0x149ed84 0x149ec9b 0x245a7d8 0x245a88a 0x1c8626 0x26d2 0x2645 0x1)
terminate called throwing an exception(lldb)
now my data snippet is: [{"k1":{"v":"0"}},{"k2":{"v":"0"}},{"k3":{"v":"0"}},{"k4":{"v":"0"}},{"k5":{"v":"0"}},{"k6":{"v":"0"}},{"k7":{"v":"1"}},{"k8":{"v":"0"}},{"k9":{"v":"1"}},{"k10":{"v":"0"}},{"k11":{"v":"1"}},{"k12":{"v":"0"}},{"k13":{"v":"1"}},{"k14":{"v":"0"}},{"k15":{"v":"0"}},{"k16":{"v":"0"}}]
but it still gives the same error.. even i decşare the iVar as NSDictionary why does it complain of nsmutable array??
The JSON you're parsing is an array, not an object. So the result of [NSJSONSerialization JSONObjectWithData...] is not an NSDictionary *, but an NSArray * instead.
For example, for the JSON data
[{"k1":{"v":"0"}}, {"k2":{"v":"0"}}]
You can use something similar to this code (don't have xcode right now to try to run it):
NSArray * arr = [NSJSONSerialization JSONObjectWithData:data options:...];
int i;
for (i = 0; i < [arr count]; i++) {
NSDictionary * dic = [arr objectAtIndex:i];
NSString * k;
for (k in [dic allKeys]) {
NSLog(#"Temporary ports: %#", [dic objectForKey:k]);
}
}

App crash after '

My application is crashing when a ' appears in the title of the JSON code i'm parsing.
This line is loading the title's:
[[cell textLabel] setText:[item objectForKey:#"title"]];
JSON:
NSString *jsonString = [NSString
stringWithContentsOfURL:[NSURL URLWithString:#"**test.php"]
encoding:NSStringEncodingConversionAllowLossy
error:nil];
// Create parser
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
parser = nil;
// Set tableData
[self setTableData:[results objectForKey:#"items"]];
Crash:
tableData NSArray * 0x00000001
2012-04-10 10:29:11.446 *[21222:f803] -[NSNull isEqualToString:]:
unrecognized selector sent to instance 0x146ace8 2012-04-10
10:29:11.447 *[21222:f803] * Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[NSNull
isEqualToString:]: unrecognized selector sent to instance 0x146ace8'
* First throw call stack: (0x13d4022 0x1565cd6 0x13d5cbd 0x133aed0 0x133acb2 0x15e0ff 0x2b10 0xb8c54 0xb93ce 0xa4cbd 0xb36f1 0x5cd21
0x13d5e42 0x1d8c679 0x1d96579 0x1d1b4f7 0x1d1d3f6 0x1db81ce 0x1db8003
0x13a8936 0x13a83d7 0x130b790 0x130ad84 0x130ac9b 0x12bd7d8 0x12bd88a
0x1e626 0x1ded 0x1d55) terminate called throwing an exception(lldb)
The key part of that crash info is: unrecognized selector sent to instance ... [NSNull isEqualToString:]
It looks like your JSON contains null somewhere that you are expecting a string. Later on, probably inside of setTableData: you will be doing something like this:
NSString* whatever = [items objectForKey:#"whatever"];
if([whatever isEqualToString:#"hello"]){
...
}
And that will crash, because the whatever variable contains NSNull, not an NSString like you were expecting.

Parsing JSON in Objective-C

I am trying to parse the JSON at this URL:
http://maps.googleapis.com/maps/api/geocode/json?address=canada&sensor=false
in Objective-C. I'm trying to get the northeast latitude under "bounds", and this is the code I've written to try and do that (feed is an NSDictionary object):
NSArray *results = [feed objectForKey:#"results"];
NSDictionary *firstResult = [results objectAtIndex:0];
NSArray *geometry = [firstResult objectForKey:#"geometry"];
NSDictionary *firstGeo = [geometry objectAtIndex:0];
NSArray *bounds = [firstGeo objectForKey:#"bounds"];
NSDictionary *northeast = [bounds objectAtIndex:0];
NSString *neLat = [[NSString alloc] initWithString:[northeast objectForKey:#"lat"]];
Even though it compiles fine and the JSON data is valid, when I run it I get this error:
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa672390
2012-02-24 01:32:06.321 Geo[570:11603] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa672390'
I don't know why this is happening, as I successfully got long_name before… any help is greatly appreciated :)
Thanks in advance!
The geometry and bounds are already dictionaries.
"geometry" : { // <-- a dictionary!
"bounds" : { // <-- also a dictionary!
"northeast" : {
"lat" : 83.1150610,
"lng" : -52.62040200000001
},
So you should write
NSDictionary *geometry = [firstResult objectForKey:#"geometry"];
NSDictionary *bounds = [geometry objectForKey:#"bounds"];
NSDictionary *northeast = [bounds objectForKey:#"northeast"];
Check the following statement.
NSArray *geometry = [firstResult objectForKey:#"geometry"];
It seems for the geometry, it does not return NSArray. It returns NSDictionary

Accessing JSON data inside an NSDictionary generated from NSJSONSerialization

Having some trouble accessing the JSON data in the following URL ( http://jamesstenson.com/portraits/?json=1 ), basically I want to access the "full" "url"'s underneath "attachments". My code at the moment is as follows:
NSError *e = nil;
NSData *jsonFeed = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://jamesstenson.com/portraits/?json=1"]];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:jsonFeed options:NSJSONReadingMutableContainers error: &e];
if (!jsonData) {
NSLog(#"Error parsing JSON: %#", e);
} else {
for(NSDictionary *item in [jsonData objectForKey:#"page"]) {
for(NSDictionary *attachment in [item objectForKey:#"images"]) {
NSLog(#"%#", attachment);
}
}
}
This keeps throwing up an error:
2011-12-21 10:13:39.362 JSON[3463:f803] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x6a7b500
2011-12-21 10:13:39.363 JSON[3463:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x6a7b500'
I am aware I am accessing the items wrongly, but cannot figure out how to achieve this. I've tried several solutions such as http://blogs.captechconsulting.com/blog/nathan-jones/getting-started-json-ios5 - but no luck. I am complete newbie to iOS development and have a little knowledge of JSON. Thanks for everyones help in advance.
The problem is in you for loop
for(NSDictionary *item in [jsonData objectForKey:#"page"])
You won't get NSDictionary in item, it will return you key of Dictionary, which would be NSString
Check this link for each loop in objective c for accessing NSMutable dictionary to know how to traverse through NSDictionay
Below is the modified code for your requirement, might help you
if (!jsonData) {
NSLog(#"Error parsing JSON: %#", e); } else {
NSArray *attachments = [[jsonData objectForKey:#"page"] objectForKey:#"attachments"];
for(NSDictionary *object in attachments) {
NSLog(#"%#", [object objectForKey:#"images"]);
NSLog(#"%#", [[[object objectForKey:#"images"] objectForKey:#"full"] objectForKey:#"url"]);
}
}