I am trying to parse a JSON array returned by a RESTful web API that looks similiar to the following (using jsonviewer the json is returned as a bunch of dictionaries in an array):
[{
"date": "2011-03-21",
"meal": "BREAKFAST",
"category": "BREAKFAST BAKERY",
"recipe": "213012",
"name": "Aesops Bagels",
"portion": "1",
"unit": "each"},
I am trying to get the "name" information and then store it into an tableview. Here is the code I am using to accomplish that:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *allDataArray = [NSJSONSerialization JSONObjectWithData:webData
options:0
error:nil];
for (NSDictionary *diction in allDataArray) {
NSDictionary *menuItem = [diction objectForKey:@"menuItem"];
NSString *name = [menuItem objectForKey:@"name"];
[array addObject:name];
}
[[self MyTableView]reloadData];
}
The error that I am getting is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
So I'm pretty sure that there is an error occurring in the line above the for loop, and this is causing the array to try to take nil
as a value. But any help figuring out what is going wrong/how to successfully parse this json would be extremely appreciated. I am very new to both json, xcode, and iOS so I apologize if I have done anything particularly stupid.
You don't actually have an item called menuItem
in your JSON sample. Your code looks as it was written to parse JSON that looks like this:
[{ "menuItem" : { "name" : "Aesops Bagels",
…
}
},
]
ie, its expecting a "menuItem" key in each dictionary in the list. If you're actually trying to parse the snippet you posted, I think you just need to simplify your loop code from this:
NSDictionary *menuItem = [diction objectForKey:@"menuItem"];
NSString *name = [menuItem objectForKey:@"name"];
to:
NSString *name = [diction objectForKey:@"name"];
You may also want to make sure that name isn't nil before you attempt to add it to your results array, just in case your data has an entry that's missing a name.
As ckhan said, your JSON object is just an array of dictionaries, without any reference to "menuitem". If in fact you don't have a "menuitem" entry in your JSON object (i.e. assuming the JSON provided in your question is representative), then it would simply be:
for (NSDictionary *diction in allDataArray)
[array addObject:[diction objectForKey:@"name"]];
Or
[allDataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[array addObject:obj[@"name"]];
}];
Or, more simply, make array
an immutable NSArray
rather than a NSMutableArray
and use the following:
NSArray *array = [allDataArray valueForKey:@"name"];
By the way, if you're really concerned that some of the dictionary entries might not have the "name" entry, while the one line valueForKey
handles that, the others would need to add the conditional logic, e.g.:
for (NSDictionary *diction in allDataArray) {
id value = diction[@"name"];
if (value == nil)
value = [NSNull null];
[array addObject:value];
};
Clearly, I'm adding a NSNull
to the array so that you know that there was a dictionary entry for which there was no name. How you want to handle this scenario (e.g., add a NSNull, simply add nothing, etc.) is up to you, but hopefully this gives you the idea. But I think the main problem was the "menuitem" reference, so this may be moot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With