Get JSON value from NSDictionary and place in NSString not working - ios

In my previous app I had this code to extract JSON from an NSDictionary variable into a string:
NSString *task_id = [jsonString objectForKey:#"key"];
It worked very well but for some reason it won't work in my new app anymore? Instead I get this error:
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x14d7bda0
Does anyone know why this might not work?
Peter

Make sure that the jsonString is NSDictionary:
if([jsonString isKindOfClass:[NSDictionary class]]) {
NSString *task_id = [jsonString objectForKey:#"key"];
} else {
// is not a dictionary
NSLog(#"%#", jsonString);
}

Related

Assigning text to UILabel gives error after parsing JSON

I've the following code for receiving response from PHP web service in JSON Format:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutableData encoding:NSUTF8StringEncoding];
NSLog(#"Response from Server : %#", responseStringWithEncoded);
[self getData:responseStringWithEncoded];
}
-(void) getData:(NSString *) responseStringWithEncoded{
NSData *data = [responseStringWithEncoded dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"object for key ime = %#", [json objectForKey:#"imei"]);
NSString * jimei = [json objectForKey:#"imei"];
NSLog(#"jimei = %#", jimei);
// NSDictionary * jimei = [json objectForKey:#"imei"];
imeiLable.text = jimei;
}
I am successfully retrieving data in simulator but when assigning one value among received string(NSDictionary) to imeiLable.text it gives following error.
Here is the output:
Request data = { URL: http://localhost/getjsonimei.php?imei=478593219801234 }
Response from Server : {"id":7,"imei":478593219801234,"mname":"Samsung Glaxy","pamount":"2000 rupees","pname":"Faizi","address":"House number 88, block 31","cnumber":11122233,"nic":"87456893"}
object for key ime = 478593219801234
jimei = 478593219801234
Here is detailed description of simulator resulting string(dictionary) and error.
2017-05-24 20:01:13.229 imiechecker[4005:61372] -[__NSCFNumber length]: unrecognized selector sent to instance 0xb01b3472adbb0923
2017-05-24 20:01:13.263 imiechecker[4005:61372] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb01b3472adbb0923'
I also tried following approach:
NSDictionary * jimei = [json objectForKey:#"imei"];
but having the same error.
Please suggest where I am doing it wrong?
Your IMEI number is of data type NSNumber, not NSString.
Try this:
NSString * jimei = [NSString stringWithFormat:#"%#", [json objectForKey:#"imei"]];
imeiLable.text = jimei;

NSTaggedPointerString objectForKey in objective-c

when I try to fetch the result from the JSON result. It throws the following exception.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString objectForKey:]: unrecognized selector sent to instance 0xa006449656c6f526'
My code.
NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutableData encoding:NSUTF8StringEncoding];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dataDict in jsonObjects) {
NSString *firstname = [dataDict objectForKey:#"FirstName"];
}
The above code throws an NSException.
My JSON response looks like this.
{
"IsExternal": 0,
"LoginId": 4,
"EmployeeId": 223,
"FirstName": "GharValueCA",
"RoleId": 4,
"LastName": null,
"Mobile": null,
"AgencyId": 100,
"BranchId": 74
}
Any help will be appreciated.
According to the definition of JSON, each JSON contains one object (which can be a collection type that contains other objects). In your case, your text starts with "{", so that's a dictionary. A single dictionary.
So NSJSONSerialization, when it reads that file, gives you back an NSDictionary containing values under keys like IsExternal, FirstName etc.
However, your code uses for( ... in ... ) on that dictionary (which, according to NSDictionary documentation, will iterate over the keys in the dictionary, which are strings), but then you treat those strings as if they were dictionaries again.
So instead of looping over the dictionary, you should just use the dictionary in jsonObjects directly, by calling something like -objectForKey: on it.
There is a misunderstanding:
jsonObjects is already the dictionary, assign the deserialized object immediately to dataDict.
NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:mutableData
options:0
error:nil];
// mutableContainers in not needed to read the JSON
The enumerated objects are strings, numbers or <null>. You called objectForKey: on a string which caused the error.
Get the name directly (no loop)
NSString *firstname = dataDict[#"FirstName"];
or you can enumerate the dictionary
for (NSString *key in dataDict) {
NSLog(#"key:%# - value:%#", key, dict[key]);
}
You should call
[jsonObjects objectForKey:#"FirstName"];
to get the FirstName value.
Below lines of code returns you (probably) a NSDictionary, so this is the container that stores all of your json values.
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
Try this code:
if ([jsonObjects isKindOfClass:[NSDictionary class]]) {
NSString *firstname = [jsonObjects objectForKey:#"FirstName"];
}
as your 'jsonObjects' is of generic type 'id' so just check that whether it is of NSDictionary type and then in if-block you can directly access it by objectForKey:
try this code, hope it help,
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
if([jsonObjects respondsToSelector:#selector(objectForKey:)]){
NSString *firstname = [jsonObjects objectForKey:#"FirstName"];
}

ios - get values from NSDictionary

I have JSON on my server, which is parsed into iOS app to NSDictionary. NSDictionary looks like this:
(
{
text = Aaa;
title = 1;
},
{
text = Bbb;
title = 2;
}
)
My question is - how to get just text from first dimension, so it should be "Aaa". I've tried to use this:
[[[json allValues]objectAtIndex:0]objectAtIndex:0];
But it didn't work, it ends with error
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFArray allValues]:
unrecognized selector sent to instance 0x714a050'
So can you help me please, how to get just one value from specified index? Thanks!
That error message is simply telling you that NSDictionary (which is the first object of that array, along with the second) doesn't respond to objectAtIndex.
This will be a bit cody, but it explains it better:
NSArray *jsonArray = [json allValues];
NSDictionary *firstObjectDict = [jsonArray objectAtIndex:0];
NSString *myValue = [firstObjectDict valueForKey:#"text"];
Your JSON object is an array, containing two dictionaries. That's how to get the values:
NSDictionary* dict1= json[0];
NSString* text= dict1[#"text"];
NSString* title= dict1[#"title"];
Try this:
NSString *txt = [[json objectAtIndex:0] objectForKey:#"text"];
UPDATE: Have fixed the error. Thanks yunas.

How to parse integer value to Json iOS?

I was passed NSstring it is coming properly data into uitableview but when I am parsing integer value it showing exception Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x744e9d0
This is my code
(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray * values=[json objectForKey:#"loans"];
NSLog(#"Array: %#",values);
for (NSDictionary *file in values)
{
NSNumber *fileTitle=[file objectForKey:#"id"];
// NSString *fileTitle = [file objectForKey:#"sector"];
[titles addObject: fileTitle];
}
[self.mainTableView reloadData];
}
You are assigning string value to NSNumber type.
Try to use this
NSString *fileTitle=[file objectForKey:#"id"];
[titles addObject: fileTitle];
and use string value.
[[titles addObject: fileTitle] stringValue];
I guess you are doing something like this in your -tableView: cellForIndexPath:
UITableViewCell *cell = [...];
cell.titleLabel.text = titles[indexPath.row];
You can only use NSString for -[UILabel setText:] method.
Convert your NSNumber to NSString with a simple -[NSNumber stringValue] or using NSNumberFormatter.
Everything seems ok. Just replace
NSNumber *fileTitle=[file objectForKey:#"id"];
by NSString *fileTitle = [file objectForKey:#"id"];

JSON Objective-C Parsing Fail

I have written the following code but I keep on getting nil. I have tried many different variations of this but I am failing exceptionally hard.
This is what I am getting from the server.
Two objects.
[{"description":"yolo.","name":"ye","id":1},{"description":"sMITH","name":"John","id":2}]
Any help would be greatly appreciated...... Thanks.
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
NSArray *jsonObjects = [jsonParser objectWithData:response];
NSMutableString *yolo = [[NSMutableString alloc] init];
for ( int i = 0; i < [jsonObjects count]; i++ ) {
NSDictionary *jsonDict = [jsonObjects objectAtIndex:i];
NSString *IDID = [jsonDict objectForKey:#"id"];
NSString *name = [jsonDict objectForKey:#"name"];
NSLog(#"ID: %#", IDID); // THIS DISPLAYS
[yolo appendString: IDID]; // THIS seems to be causing the new error...
[yolo appendString:#": "];
[yolo appendString: name];
NSLog(#"%#", yolo); // RETURNS NIL
}
EDIT:
currently my new error is...
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSDecimalNumber length]:
unrecognized selector sent to instance 0x81b89f0'
Looks like your [jsonDict objectForKey:#"id"] is an NSNumber(or NSDecimalNumber) and not an NSString. You should change the line NSString *IDID = [jsonDict objectForKey:#"id"]; to,
id myObject = [jsonDict objectForKey:#"id"];
NSString *IDID = nil;
if ([myObject isKindOfClass:[NSNumber class]]) {
IDID = [[jsonDict objectForKey:#"id"] stringValue];
} else {
IDID = [jsonDict objectForKey:#"id"];
}
This error appeared now since earlier you were not initializing NSMutableString *yolo and you were using appendString: on a nil object. Since now it is initialized as NSMutableString *yolo = [[NSMutableString alloc] init]; it is trying to call appendString on NSMutableString object which accepts only NSString type as its inputs where as you are passing an NSNumber in it. length is a method which appendString: internally calls. So you need to change this as well.
You never initialize yolo, so it's just nil the whole time you're calling -appendString: on it. Try this:
NSMutableString *yolo = [NSMutableString string];
Have you tried initializing the NSMutableString?
NSMutableString *yolo = [[NSMutableString alloc] init];
It looks like you are not really checking the type of the data coming to your app via your JSON feed. This might be the case of random crashes when users actually use your app. It might be also a reason for rejection to the App Store, is such crashes happen during your App's review.
You should be checking the type of all objects you receive from JSON, before calling methods on them :)
By implementing best practices you will have a stable and usable app. Build data models to validate your data. You can also you a JSON data model framework like JSONModel: http://www.jsonmodel.com/
It's obvious from your data that "id" is not a string, but a number. Assigning a pointer to an NSString* doesn't magically convert it to an NSString*. And it's obvious from the exception that you got that some object is an NSDecimalNumber when you thought it would be an NSString.
So: IDID is an NSNumber*, and pretending it is an NSString* will lead to crashes.

Resources