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

StackOverflow https://stackoverflow.com/questions/21105592

Question

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

Was it helpful?

Solution

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
    ...
}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top