JSON parsing error in Objective-C - ios

I am trying to parse this JSON in Objective-C. The response object looks thus:
(
{
"Year": "2003",
"SumOfYear": "0.20"
},
{
"Year": "2004",
"SumOfYear": "0.64"
},
{
"Year": "2005",
"SumOfYear": "0.90"
}
)
I tried the following
NSDictionary* dictionaryObtained = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"dict = %#",dictionaryObtained);
NSDictionary *yearsObtained = [dictionaryObtained objectForKey:#"Year"];
But I obtain the following error:
-[__NSCFArray bytes]: unrecognized selector sent to instance 0x18a3bfd0
Where am I going wrong?
I want to obtain all the Year in a NSArray and all the SumOfYear in another NSArray.
The error is from this line
NSDictionary* dictionaryObtained = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];

It appears (hard to tell for sure without better info from you) that responseObject has already been parsed from JSON string into Objective-C objects. Therefore you should not run it through NSJSONSerialization again.
But what you have is an NSArray, so, assuming you want to collect an array of the "Year" values, you need something along the lines of:
NSMutableArray* yearsObtained = [NSMutableArray array];
for (NSDictionary* dictionaryObtained in responseObject) {
NSLog(#"dict = %#",dictionaryObtained);
NSString* year = [dictionaryObtained objectForKey:#"Year"];
NSLog(#"year = %#", year);
[yearsObtained addObject:year];
}

You have wrong(right format - but not to match your code) the json.
If you want your code to work this is the correct:
{ "Year":
[
{
"Year": "2003",
"SumOfYear": "0.20"
},
{
"Year": "2004",
"SumOfYear": "0.64"
},
{
"Year": "2005",
"SumOfYear": "0.90"
}
]
}
Your json as it is can be parsed:
for(NSDictionary *myDict in jsonObj){
NSString *year = [myDict objectForKey:#"Year"];
}

I would suggest to do it like that:
NSArray * dataArray = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
for(NSDictionary * diction in dataArray)
{
NSLog(#"%#",[diction objectForKey:#"Year"]);
}
because you have an array of dictionaries you should put a JSONSerialization inside an NSArray
then to go inside it with dictionary thus u can get to your years as you wish.
From comments below it seems like your responseObject is already parsed
so you can just go
for(NSDictionary* dict in responseObject)
{
NSLog(#"%#",[dict objectForKey:#"Year"]);
}

The simplest way to parse your JSON and get two arrays is
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
NSArray *years = [jsonArray valueForKeyPath:#"Year"];
NSArray *sums = [jsonArray valueForKeyPath:#"SumOfYear"];
KVC is a great instrument for parsing data structures.

Related

NSAarry to NSDictionary

I have an NSArray that looks like this
NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"main: %#", [dataDict valueForKey:#"main"]);
main: [{"city": "dallas", "description": "this is my test description"}]
And I am trying to turn it into a NSDictionary so I get get element like [mainDict objectForKey#"city"]
So I tried this
NSLog(#"%#", [[mainArray objectAtIndex:0] objectForKey:#"city"]);
Thinking it would get the first element in mainArray and then the object that I want but I keep getting this error
[__NSCFString objectAtIndex:]: unrecognized selector sent to instance
How can I make the NSAarry into a NSDictionary?
Thanks
Create a for loop for list when you get response in [{},{}] format that means its a list of elements . Or you can ask your API developer to correct the error .
Any ways simple solution here is :
for (NSDictionary *d in [dataDict valueForKey:#"main"]){
NSlog (#"%#",d);
NSlog (#"%#",[d objectForKey :#"city"]);
}
Your error is saying mainarray is not a NSArray, it is NSString. So please check like this
NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"main: %#", [dataDict valueForKey:#"main"]);
if ([[dataDict valueForKey:#"main"] isKindOfClass:[NSArray class]]) {
NSArray *mainArray = [dataDict valueForKey:#"main"];
NSLog(#"City == %#",[[mainArray objectAtIndex:0] objectForKey:#"city"]);
}else{
NSLog(#"mainarray is kind of -> %#", NSClassFromString([dataDict valueForKey:#"main"]));
}
NSArray *mainArray = #[#{#"city":#"dallas", #"description":#"this is my test description"}];
NSLog(#"%#", [[mainArray objectAtIndex:0] objectForKey:#"city"]);
no problem ....

IOS Dev Fetching JSON Data

I am a novice at IOS dev and i really need some help.
I want to parse (which is working) and fetch some JSON Data.
i used this tutorial for the http request and json parsing
http://www.mysamplecode.com/2013/04/ios-http-request-and-json-parsing.html
everything works fine with a 1 dimensional dictionary
but I need to be able to fetch the following JSON Data
[{"defaultGateway": "10.10.10.254", "hostname": "On", "connected": "true", "subnetMask": "255.255.255.255", "iPAddress": "10.10.10.10", "dhcpEnabled": "true"},
{"defaultGateway": "10.10.10.254", "hostname": "On", "connected": "true", "subnetMask": "255.255.255.255", "iPAddress": "10.10.10.10", "dhcpEnabled": "true"}]
after I use the following function I got the following dictionary which I really don't know how to access
NSDictionary * res = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
here is a picture of the dictionary
http://www11.pic-upload.de/09.11.14/5n4hdg3eh84q.png
How can I access for example the defaultGateway in the first dictionary?
You have a small logical error in your example. The expression [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; returns an NSArray and not and NSDictionary. So, first you should change this part to:
NSArray *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
I know it's an array because your JSON string contains an array of two JSON objects. NSJSONSerialization will transform JSON arrays into objects of type NSArray and JSON objects into objects of type NSDictionary.
If you're not sure what your JSON contains, you can do the following:
id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if ([result isKindOfClass:[NSArray class]]){
// do something with the array
}
else if ([result isKindOfClass:[NSDictionary class]]){
// do something with the dictionary
}
As for your question, you can access the data in an NSDictionary by providing a key, which you can do in two ways:
NSString *gateway = [dictionary objectForKey:#"defaultGateway"];
or even faster:
NSString *gateway = dictionary[#"defaultGateway"];
Coming back to your example, to access the defaultGateway from the first of your two JSON objects, you can do the following:
NSArray *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; // parse the JSON and store in array
NSDictionary *dict = result[0]; // take the first of the two JSON objects and store it in a dictionary
NSString *gateway = dictionary[#"defaultGateway"]; // retrieve the defaultGateway property

How to parse a Nested JSON

Thank you reading my post, I known this topic was asked so many time, and I had saw that but no luck...
I want to parse a simple JSON string, as followings:
[
{
"id":"1",
"name_en":"Photography",
"subchannels":[
{
"id":"4",
"name_en":"John"
},
{
"id":"18",
"name_en":"Sam"
}
]
},
{
"id":"7",
"name_en":"Equipment",
"subchannels":[
{
"id":"25",
"name_en":"ABC Company"
},
{
"id":"40",
"name_en":"CDE Company"
}
]
}
]
It had convert this string to NSDictionary
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *testDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&e];
Then I list the Dictionary Key
for(id key in testDic) {
NSLog(#"%#", key);
}
The result is the entire record as the Dictionary Key, so I can't use [testDic objectForKey:key] to retrieve the value.
How can I get the first row name_en and the second row subchannels value?
(is it possible to retrieve easily like xpath in XML?)
Thank you for helping.
First of all. The root object of your model is NSArray object - not `NSDictionary. '[]' means array and {} means dictionary.
NSArray *dataArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&e];
for (NSDictionary *entry in dataArray) {
NSString *name = entry[#"name_en"];
NSArray *subchannels = entry[#"subchannels"]; //array of dictionaries
NSLog(#"Name %s", name);
for (NSDictionary *subchannel in subchannels) {
NSLog(#"Subchannels name %# id: %d", subchannel[#"name"], [subchannel[#"id"] integerValue]);
}
}
If you want to perform advances JSON parsing I encourage you to look at Mantle github project.

Parsing JSON dictionary with multiple arrays with NSJSONSerialization does not result in NSDictionary or NSArray

I am trying to parse a JSON dictionary in the form of:
{
"bible": {
"book": [
{
"bookName": "Genesis",
"chapter": [
{
"chapterNum": "1",
"verse": [
{
"verse": "In the beginning God created the heaven and the earth.",
"verseNum": "1"
},
{
"verse": "And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters.",
"verseNum": "2"
},
I am having difficulties getting to the proper data within this structure. My goal is to create a Verse managed object that has a verseNum, verse (the text), chapterNum, and bookName properties.
I need help creating the object. Currently, when I create the NSDictionary using NSJSONSerialization, I only obtain one dictionary, with a single NSCFString:
NSError* err = nil;
NSString* dataPath = [[NSBundle mainBundle] pathForResource:#"kjv"
ofType:#"json"];
NSDictionary *bible = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath]
options:kNilOptions
error:&err];
for (NSDictionary *book in [bible valueForKey:#"bible"]) {
NSLog(#"%#", book);
}
The console output simply reads: book
Try the following code:
NSError *error = nil;
id JSONResponse = [NSJSONSerialization JSONObjectWithData:self.responseData
options:0
error:&error];
if (error) {
NSLog(#"JSON Error: %#", error);
return;
}
// Should be an NSDictionary or NSArray
NSLog(#"JSON response: %#", [JSONResponse description]);
NSArray *books = [JSONResponse valueForKeyPath:#"bible.book"];
for (NSDictionary *book in books) {
NSLog(#"%#", book);
NSString *bookName = [book valueForKey:#"bookName"];
NSArray *chapters = [book valueForKey:#"chapter"];
// loop through the chapters
...
NSArray *verses = [book valueForKey:#"verse"];
// loop through the verses
...
}
Seems your JSON document is an object (dictionary), containing one element named "bible". bible is itself a dictionary containing one element named "book". book is an array. The array elements are objects, with an item "bookName" containing a string, and another item "chapter" containing an array and so on. So:
NSDictionary* JSONResponse = ...
NSAssert ([JSONResponse isKindOfClass:[NSDictionary class]]);
NSDictionary* bible = JSONResponse [#"bible"];
NSAssert ([bible isKindOfClass:[NSDictionary class]]);
NSArray* books = bible [#"book"];
NSAssert ([books isKindOfClass:[NSArray class]]);
for (NSDictionary* book in books)
{
NSAssert ([book isKindOfClass:[NSDictionary class]]);
NSString* bookName = book [#"bookName"];
NSArray* chapters = book [#"chapter"];
}
and so on.

filter Subdata's in JSON data in IOS

I am new to iOS & JSON parsing I'm Getting some JSON data like,
[
{
"id":3,
"name":"SCORM 0",
"visible":1,
"summary":"",
"summaryformat":1,
"modules":[
{
"id":1,
"url":"http:\/view.php?id=1",
"name":"Course01",
"visible":1,
"modicon":"http:\theme\/image.php\/standard\/scorm\/1378190687\/icon",
"modname":"scorm",
"modplural":"SCORM packages",
"indent":0
},
{
"id":2,
"url":"http:\/\/192.168.4.196\/moodle\/mod\/forum\/view.php?id=2",
"name":"News forum",
"visible":1,
"modicon":"http:\//image.php\/standard\/forum\/1378190687\/icon",
"modname":"settle",
"modplural":"Forums",
"indent":0
}
]
},
{
"id":2,
"url":"http:\/\/view.php?id=2",
"name":"News forum",
"visible":1,
"modicon":"http:\/\theme\/image.php\/standard\/forum\/1378190687\/icon",
"modname":"forum",
"modplural":"Forums",
"indent":0
}
]
I need to separate the data's with respect to "modname" != "forum" and store the respective data's in the array.
Helps and Solutions will be appreciated.
NSMutableArray *jsonArray = [[NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &e] mutableCopy];
jsonArray = [jsonArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return ![evaluatedObject[#"modname"] isEqualToString:#"forum"];
}];
This is a sketch of what you could do
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];
NSLog(#"%#",json);
NSLog(#"%#",delegate.firstArray);
NSArray * responseArr = json[#"Deviceinfo"];
for(NSDictionary * dict in responseArr)
{
[delegate.firstArray addObject:[dict valueForKey:#"id"]];
[delegate.secondArray addObject:[dict valueForKey:#"name"]];
[delegate.thirdArray addObject:[dict valueForKey:#"visible"]];
[delegate.fourthArray addObject:[dict valueForKey:#"summery"]];
}
here all data arrange as per your key

Resources