0

I'm trying to parse the following JSon (which was validated I think last time I checked):

{
    "top_level" =     (
                {
            "download" = "http:/target.com/some.zip";
            "other_information" = "other info";
            "notes" =             (
                                {
                    obj1 = "some text";
                    obj2 = "more notes";
                    obj3 = "some more text still";
                }
            );
            title = "name_of_object1";
        },
                {
            "download" = "http:/target.com/some.zip";
            "other_information" = "other info";
            "notes" =             (
                                {
                    obj1 = "some text";
                    obj2 = "more notes";
                    obj3 = "some more text still";
                }
            );
            title = "name_of_object2";
        },
                {
            "download" = "http:/target.com/some.zip";
            "other_information" = "other info";
            "notes" =             (
                                {
                    obj1 = "some text";
                    obj2 = "more notes";
                    obj3 = "some more text still";
                }
            );
            title = "name_of_object3";
        }
    );
}

My attempt is using the following:

NSDictionary *myParsedJson = [myRawJson JSONValue];

for(id key in myParsedJson) {
    NSString *value = [myParsedJson objectForKey:key];
    NSLog(value);
}

Error:

-[__NSArrayM length]: unrecognized selector sent to instance 0x6bb7b40

Question: It seems to me that JSon value makes myParsedJson object an NSArray instead of a NSDictionary.

How would I iterate through the objects called name_of_object and access each of the nested dictionaries? Am I going about it the right way?

stackOverFlew
  • 1,479
  • 2
  • 31
  • 58
  • Jesse having already given what I think is the correct answer, I'll make the standard indirectly related comment: since iOS 5 Apple have supplied a built-in JSON parser; you're probably using it for a good reason but don't expect SBJSON parser to be well supported in the future. – Tommy Oct 03 '12 at 01:42
  • oh thanks Tommy; I wasn't aware of that at all. – stackOverFlew Oct 03 '12 at 02:41
  • @Tommy, what makes you think that? I am the author of SBJson and have no intention to stop supporting it. – Stig Brautaset Oct 03 '12 at 09:16
  • @StigBrautset simple speculation about usage; you'll be seeing significantly lower uptake now as your work — great though it is — no longer has a strong use case. When projects are no longer so vital most authors will reinvest their talent in a new project. You're obviously a talented person so my speculation was that you'll be more likely to focus on something people are more likely to use. – Tommy Oct 03 '12 at 16:48
  • @Tommy granted, but then it's pretty mature by now and doesn't actually require much effort to maintain. Additionally it has features which Apple's parser does not, so it still has a place even on iOS 5 and above. – Stig Brautaset Oct 03 '12 at 22:10

2 Answers2

2

The first argument of NSLog must be a string. Try this:

NSLog(@"%@", value);
Jesse Rusak
  • 56,530
  • 12
  • 101
  • 102
  • but it's already a string since value refers to an nsstring object?.... (some time later after running it... and it actually working) wait... why do i need to cast a string into a string? – stackOverFlew Oct 03 '12 at 02:40
  • This is not a cast. NSLog accepts a *format* string, not a string variable. Also `%@` does not mean "string" either. It means "object" – borrrden Oct 03 '12 at 03:08
  • Just to clarify @borrrden's statement: it's perfectly fine to keep a format string in a variable, but it is unsafe to not use one if you attempt to print data you don't control, as someone could craft a format string that would crash your app. – Stig Brautaset Oct 03 '12 at 09:24
1

Your value is not a string, just because you've typed it so. Based on the structure you posted you will have an array as your top-level object.

NSDictionary *myParsedJson = [myRawJson JSONValue];
for(id key in myParsedJson) {
    id value = [myParsedJson objectForKey:key];
    NSLog(@"%@", value);
}

The %@ syntax in NSLog causes the -description method to be called on value; this method returns an NSString. That means that you could do NSLog([value description]); but this is generally not a good idea. (Someone could craft malicious input that could crash your app.)

Stig Brautaset
  • 2,602
  • 1
  • 22
  • 39