objective-c JSON literals, nested - most elegant solution?

208 Views Asked by At

Say you do this,

NSString *teste = yourData[@"title"];

no problem if "title" is completely missing in the json: you just get null. If you do this:

NSString *teste = yourData[@"location"][@"city"];

if "city" is missing in the json nest, no problem. if the whole "location" section does not exist, again no problem

However! You'll often see json like this, " largeImage = "<null>"; "

In that case, the app will crash if you are using the code above.

In practice you have to do this:

NSString *imageUrl = nil;
if ([yourResults[thisRow][@"largeImage"] isKindOfClass:[NSDictionary class]])
    imageUrl = yourResults[thisRow][@"largeImage"][@"URL"];

My question was really:

is there some dead clever way to perhaps override the literal syntax (ie, override the underlying message, perhaps??) to cover this problem?

So essentially, make this concept [@"blah"] basically first check that indeed it is a dictionary at hand, before trying the operation.

It's a shame because, effectively, you can never use this wonderful syntax

yourData[@"location"][@"city"]

in practice, due to the problem I outline.

PS sorry for the earlier confusion on this question, fixed by Paramag. below - good one Paramag.

3

There are 3 best solutions below

3
On

Personally i use with JSON category which returns null instead NSNull so my code looks:

[[json objectForKeyNotNull:@"Key"] objectForKeyNotNull:@"Other"]

As you want to have code shorter, i think i would create the category on NSDictionary which could be used as :

[json objectForPath:@"Key.Value"]

Which would expand the path into the keys.

There is some nice gist which looks like it's doing it:

https://gist.github.com/Yulong/229a62c1188c3c024247#file-nsdictionary-beeextension-m-L68

1
On

to check this kind of null , you can use valueForKeyPath:

NSString *teste = [CLOUD.yourData[thisRow] valueForKeyPath:@"location.city"];

it will first check for "location" and then for "city".

1
On

I would say this is a problem with your schema. null in JSON and a dictionary (called an "object") in JSON are different types of things. The fact that your key can have a value that is sometimes null and sometimes a dictionary seems to me that you guys are not following a rigorous schema.

A good design would have the key either not be there, or if it is there, its value is guaranteed to be a dictionary. In such a case, the Objective-C code NSString *teste = yourData[@"location"][@"city"]; would work without modification because if the key "location" didn't exist, then its value would be nil in Objective-C, and subsequent accesses won't crash, and will also return nil.