Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TouchJSON, dealing with NSNull

Hi I am using TouchJSON to deserialize some JSON. I have been using it in the past and on those occasions I dealt with occurrences of NSNull manually. I would think the author had to deal with this as well, so me doing that again would just be overhead. I then found this in the documentation:

Avoiding NSNull values in output.

NSData *theJSONData = /* some JSON data */
CJSONDeserializer *theDeserializer = [CJSONDeserializer deserializer];
theDeserializer.nullObject = NULL;
NSError *theError = nil;
id theObject = [theDeserializer deserialize:theJSONData error:&theError];}

The way I understand it the user of the class can pass a C-style null pointer to the deserializer and when it encounters a NSNull it will insert the values (NULL) passed to it. So later on when I use the values I won't get NSNull, but NULL.

This seems strange, the return value is an NSDictionary which can only contain Objects, shouldn't the value default to 'nil' instead?

If it is NULL can I check the values like this?

if([jsonDataDict objectForKey:someKey] == NULL)

It would seem more logically to be able to do this:

if(![jsonDataDict objectForKey:someKey])

No to mention all the cases where passing nil is allowed but passing NULL causes a crash.

Or can I just pass 'nil' to the deserializer?

Much of this stems from me still struggling with nil, NULL, [NSNULL null], maybe I am failing to see the potential caveats in using nil.

like image 953
RickiG Avatar asked Apr 19 '11 13:04

RickiG


2 Answers

For another JSON library, but with the same issues, I've created the following category on NSDictionary:

@implementation NSDictionary (Utility)

// in case of [NSNull null] values a nil is returned ...
- (id)objectForKeyNotNull:(id)key {
   id object = [self objectForKey:key];
   if (object == [NSNull null])
      return nil;

   return object;
}

@end

Whenever I deal with JSON data from said library, I retrieve values like this:

NSString *someString = [jsonDictionary objectForKeyNotNull:@"SomeString"];

This way the code in my projects become a lot cleaner and at the same time I don't have to think about dealing with [NSNull null] values and the like.

like image 129
Wolfgang Schreurs Avatar answered Oct 30 '22 06:10

Wolfgang Schreurs


nil and NULL are actually both equal to zero, so they are, in practice, interchangeable. But you're right, for consistency, the documentation for TouchJSON should have used theDeserializer.nullObject = nil instead of NULL.

Now, when you do that, your second predicate actually works fine:

if (![jsonDataDict objectForKey:someKey])

because TouchJSON omits the key from the dictionary when you have nullObject set to nil (or NULL). When the key doesn't exist in the dictionary, NSDictionary returns nil, which is zero so your if condition works as you expect.

If you don't specify nullObject as nil, you can instead check for null like so:

if ([jsonDataDict objectForKey:someKey] == [NSNull null])
like image 24
Daniel Dickison Avatar answered Oct 30 '22 06:10

Daniel Dickison