Reputation: 2419
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.
Upvotes: 1
Views: 251
Reputation: 438407
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.
Upvotes: 2
Reputation: 107231
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]];
Upvotes: 1