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"];
Related
this is the json string that i am receiving from the API:
"incentives_and_benefits" = "{\"food\":{\"0\":\"\"},\"commission\":{\"0\":\"\"},\"uniform\":{\"0\":\"\"},\"transport\":{\"0\":\"\"},\"extras\":{\"0\":\"\"}}";
and i assigned it to dictionary. Now I need to get the values inside the dictionary.
I tried using the solution given here: How to get values from dict
Heres what I have so far:
NSString *strIncentives = [[self.jobDetailDict objectForKey:#"sub_slots"] objectForKey:#"incentives_and_benefits"];
NSData *jsonData = [strIncentives dataUsingEncoding:NSUTF8StringEncoding];
NSError *e;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e];
NSLog(#"DICT: %#", dict);
NSString *food = [dict objectForKey:#"food"];
NSLog(#"DICT: %#", food);
NSString *commission = [dict objectForKey:#"commission"];
NSLog(#"DICT: %#", commission);
NSString *uniform = [dict objectForKey:#"uniform"];
NSLog(#"DICT: %#", uniform);
NSString *transport = [dict objectForKey:#"transport"];
NSLog(#"DICT: %#", transport);
NSString *extras = [dict objectForKey:#"extras"];
NSLog(#"DICT: %#", extras);
Now I need to check whether food's value is 0 or 1..When Food's value is 1 then i need to get Hello string and display it. (this is just an example) food: {"1":"Hello"}
if([food isEqualToString:#""])
{
//the string will be placed here
NSLog(#"FOOD Available")
}
when i reach the if statement i get an error:
[__NSCFDictionary isEqualToString:]: unrecognized selector sent to instance
How will i be able to resolve this?
please help and thank you in advance.
if([[dict objectForKey:#"food"]isEqualToString:#“”]){
NSLog(#"FOOD Available")
}
I'm trying to acces my JSON in Objective-C from a higher scope. But it keeps crashing and I have no idea why.
The following code works:
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONOnkectWithData: responseData
options:kNilOptions
error:&error];
NSArray* nameAndPlace = [[json objectForKey:#"objects"] objectForKey:#"havens"];
//NSArray* productArray = [[json objectForKey:#"objects"] objectForKey:#"products"];
NSLog(#"FROM ---> %#", nameAndPlace);
for (NSDictionary *mapPointLoop in nameAndPlace) {
NSString * name = [mapPointLoop objectForKey:#"name"];
NSString * longitudeGet = [mapPointLoop objectForKey:#"longitude"];
NSString * latitudeGet = [mapPointLoop objectForKey:#"latitude"];
myAnnotation *annotation1 = [[myAnnotation alloc] init];
CLLocationCoordinate2D coordinate1;
coordinate1.longitude = longitude;
coordinate1.latitude = latitude;
annotation1.coordinate = coordinate1;
annotation1.title = name;
[mainMap addAnnotation:annotation1];
//NSLog(#"FROM ---> %#", mapPointLoop);
}
}
But when I use this it crashes:
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* nameAndPlace = [json objectForKey:#"objects"];
//NSArray* productArray = [[json objectForKey:#"objects"] objectForKey:#"products"];
NSLog(#"FROM -> %#", nameAndP1ace);
for (NSDictionary *mapPointLoop in nameAndPlace) {
NSString * name = [[mapPointLoop objectForKey:#"havens"] objectForKey:#"name"];
NSNumber * longitudeGet = [mapPointLoop objectForKey:#"longitude"];
NSNumber * latitudeGet = [mapPointLoop objectForKey:#"latitude"];
float latitude = [latitudeGet floatvalue];
float longitude = [longitudeGet floatvalue];
myAnnotation *annotation1 = [[myAnnotation alloc] init];
CLLocationCoordinate2D coordinate1;
coordinate1.longitude = longitude;
coordinate1.latitude = latitude;
annotation1.coordinate = coordinate1
annotation1.title = name;
[mainMap addAnnotation:annotation1];
//NSLog(#"FROM -> %#", mapPointLoop):
}
}
It crashes with the error...
2014-05-20 17:49:57.709 labelAPortTest[5556:60b] * Terminating app
due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFString objectForKey:]: unrecognized selector sent to instance
0x1172426b0'
It crash because when you take the name:
NSString *name = [[mapPointLoop objectForKey:#"havnes"] objectForKey:#"name"];
this:
[mapPointLoop objectForKey:#"havens"]
is an NSArray and not an NSDictionary with the key name.
In fact in your first code you take the objectForKey:#"objects"] objectForKey:#"havens]"
so you have this situation:
NSDictionary ~> objects ~> NSDictionary ~> havens ~> NSArray (of NSDictionary)
then you go to through a for cycle getting 1 to 1 the NSDictionary in the NSArray.
Second case (that crash):
NSDictionary ~> objects ~> NSDictionary
but your are putting that in an NSArray going again with the for cycle..on an NSDictionary.
But it keeps crashing and I have no idea why.
The reason is right here:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x1172426b0'
You have an uncaught exception. Furthermore, you have some information about what that exception is, namely that you're sending the objectForKey: message to an object that doesn't implement it.
The first thing you should do is to set a breakpoint for all exceptions:
That'll cause the debugger to stop as soon as the exception is thrown instead of waiting until the app exits, which will give you a lot more context. You should be able to see which object is getting the unknown message. If that doesn't make the problem completely clear, set a breakpoint a line or two before the exception happens and step through the code a line at a time until you find the problem.
I'm newbie in iOS. And I'm having a problem accessing my JSON file that I retrieve in my web app server.
JSON:
{
"content": [
{
"info": [
{
"type": "TEL",
"label": "Call Phone",
"id": "32d7da39-39cc-4319-ab76-e67db9385722"
}
],
"name": "myname",
"title": "myname_title",
"image": "",
}
],
"timestamp": 1370491676,
"error": "SUCCESS"
}
I convert NSData to JSON :
NSMutableDictionary *mydatas =[NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
When I'm using this code to retrieve the name:
NSString *name = [[mydatas objectForKey:#"content"] objectForKey:#"name"];
It terminate the program.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x71e3240'
Include SBJSon Framework from here
NSString *responseString = [[NSString alloc]initWithData: urlData encoding:NSUTF8StringEncoding];
//NSLog(#"%#",responseString);
NSDictionary * mydatas = [responseString JSONValue];
NSString *name = [[mydatas objectForKey:#"content"]objectForKey:#"name"];
content is an NSArray, not an NSDictionary. You need to use NSArray calls to retrieve the item in the array:
// Be sure to check that the array has at least one item or you'll throw an exception
NSArray *contentArray = [mydatas objectForKey:#"content"];
if ( contentArray.count > 0 ) {
NSString *image = [contentArray[0] objectForKey:#"name"];
}
Why you are not using the SBJSON framework . https://github.com/stig/json-framework/.
Then refer following SO question :How to parse JSON into Objective C - SBJSON . This will be easy for you to parse this data.
NSArray *contentArray = [mydatas objectForKey:#"content"];
[contentArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"name of content at index %i is == %#",idx,[obj valueForKey:#"name"]);
}];
By looking at your JSON I can say,
Your mydatas dictionary contains 3 keys which are content, timestamp, error
The object for key content is an array. If you want to retrieve the object for key name you need to do the following
if([[mydatas objectForKey:#"content"] count]>0)
{
NSString *name = [[[mydatas objectForKey:#"content"] objectAtIndex:0]objectForKey:#"name"];
}
This will work.
try like this,
NSString *name = [[[mydatas objectForKey:#"content"] objectAtIndex:0]objectForKey:#"name"];
Try This One
NSMutableDictionary *mydatas =[NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
Save it to Array
NSArray *array = [mydatas objectForKey:#"content"];
for (int i=0; i<[array count]; i++) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"info"] forKey:#"info"];
[someArray addObject:dic];
[typeArray addObject:[[dic valueForKey:#"info"] valueForKey:#"type"] valueForKey:#"name"]];
NSString * NameStr = [typeArray objectAtIndex:i];
NSLog(#"String For Name : %#",NameStr);
[dic release];
}
Hope its Work!!!!!!!!!!!
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.
I have designed an app, which would have a button and three labels.
When the button is pressed, an URL is called. The JSON representation of the URL is as follow:
[
{
"_id": "50c87e8a1898044ea1458e4c",
"value": "10",
"time": "12:10",
"date": "12.12.12"
},
{
"_id": "50c87f311898044ea1458e4d",
"value": "12",
"time": "13:15",
"date": "12.12.12"
}
]
I also have three label in my app, that would display the value, time and date.
The code for my app is as follow:
-(IBAction)getrequest:(id)sender
{
NSURL *url =[NSURL URLWithString:#"http://localhost:3000/lights"];
NSData* data = [NSData dataWithContentsOfURL:url];
//fetch the data to the JSON Foundation opject.
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
}
- (void)fetchedData:(NSData *)responseData {
NSError *e = nil;
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
NSLog(#"%#", json);
[self processData:json];
}
-(void)processData:(NSDictionary *) JSONObject{
NSString *value = [JSONObject valueForKey:#"value"];
NSString *date = [JSONObject valueForKey:#"date"];
NSString *time = [JSONObject valueForKey:#"time"];
NSLog(#"value: %#", value);
NSLog(#"date: %#", date);
NSLog(#"time: %#", time);
_value.text = value;
_date.text = date;
_time.text = time;
}
The code compiles and builds without any error, but when I press the button in my simulator I get an exception as follow:
2012-12-12 14:16:21.115 Sensor_visulization[7956:11303] value: (
10,
12
)
2012-12-12 14:16:21.116 Sensor_visulization[7956:11303] date: (
"12.12.12",
"12.12.12"
)
2012-12-12 14:16:21.116 Sensor_visulization[7956:11303] time: (
"12:10",
"13:15"
)
2012-12-12 14:16:21.116 Sensor_visulization[7956:11303] -[__NSArrayI isEqualToString:]: unrecognized selector sent to instance 0x7191a30
2012-12-12 14:16:21.117 Sensor_visulization[7956:11303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI isEqualToString:]: unrecognized selector sent to instance 0x7191a30'
Is there any problem with my json parser?
Can I store all the values, time, date in an array?
and display the last item in the array on the label?
Any help would be really appreciated.
There seems to be a general confusion about what valueForKey does when your json object is an array of dictionary entries. Midhun's answer, solves it one way, by passing only one dictionary entry to processData (which was a logical solution because your original code's declaration of NSString *value clearly implied that you were expecting only one dictionary entry to be passed to it).
But, if you want to get arrays for all three dictionary keys for your array of dictionaries, you'd use your original fetchedData, and use valueForKey against the original json object to return NSArray objects. To do that, I'd suggest, a couple of slight modifications of your original code:
- (void)fetchedData:(NSData *)responseData {
NSError *e = nil;
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
NSLog(#"%#", json);
[self processData:json];
}
-(void)processData:(NSDictionary *) JSONObject{
// get the three array structures
NSArray *value = [JSONObject valueForKey:#"value"];
NSArray *date = [JSONObject valueForKey:#"date"];
NSArray *time = [JSONObject valueForKey:#"time"];
// these log statements demonstrate that value, date, and time are arrays
NSLog(#"value: %#", value);
NSLog(#"date: %#", date);
NSLog(#"time: %#", time);
// now, let's grab the last object from each to populate our controls
_value.text = [value lastObject];
_date.text = [date lastObject];
_time.text = [time lastObject];
}
By the way, in one of your comments, you made a parenthetical reference to wanting to chart these results. If that's the case, I might imagine that you need the dates and times combined, into NSDate objects. If you want them as NSDate objects, you could:
-(void)processData:(NSDictionary *) JSONObject{
// get the values
NSArray *value = [JSONObject valueForKey:#"value"];
// get the datetimes
NSMutableArray *datetimes = [NSMutableArray array];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"dd.MM.yy HH:mm";
formatter.locale = [NSLocale currentLocale];
for (NSDictionary *dictionary in JSONObject)
{
NSString *datetimeString = [NSString stringWithFormat:#"%# %#", [dictionary objectForKey:#"date"], [dictionary objectForKey:#"time"]];
NSDate *datetime = [formatter dateFromString:datetimeString];
[datetimes addObject:datetime];
}
NSLog(#"values=%#", values);
NSLog(#"datetimes=%#", datetimes);
Because your sample data features today's unique date, 12/12/12, I wasn't able to determine your date format, so I guessed you're using dd.MM.yy, but obviously use whatever date format string makes sense for your JSON data.
json is a NSMutableArray you are passing it to processData method as NSDictionary parameter.
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
Change the method call like:
[self processData:[json objectAtIndex:0]];
The above will display first element. If you need to display the last element use:
[self processData:[json objectAtIndex:[json count]-1]];