IOS: Detecting NSNull from JSON Not Working

889 views Asked by At

The following code designed to catch an NSNull in Json results is throwing an exception when the response is null.

 NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"jsonResults are:%@",jsonResults);
                if (![jsonResults isKindOfClass:[NSNull class]]&&!
[jsonResults[@"response"][@"insert_id"]isKindOfClass:[NSNull class]]&&!
(jsonResults==nil)){
    //do something
    }

When the exception occurs, the line beginning if (![json... is in green and the error message reads:

     Results: {
        code = 400;
        response = "0(NSNull)";
    }
    2016-05-26 07:18:06.327 idaru[385:60b] -[NSNull 
objectForKeyedSubscript:]: unrecognized selector sent to instance 
0x38871a70
    2016-05-26 07:18:06.329 myapp[385:60b] *** Terminating app due to 
uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull 
objectForKeyedSubscript:]: unrecognized selector sent to instance 
0x38871a70'

Can anyone suggest what could be wrong here?

Of note, I do have a category that supposedly converts NSNulls into 0s. Not sure how this interacts with above but here it is:

//NSNull+JSON.m
@implementation NSNull (JSON)

- (NSUInteger)length { return 0; }

- (NSInteger)integerValue { return 0; };

- (float)floatValue { return 0; };

- (NSString *)description { return @"0(NSNull)"; }

- (NSArray *)componentsSeparatedByString:(NSString *)separator { return @[]; }

- (id)objectForKey:(id)key { return nil; }

- (BOOL)boolValue { return NO; }

@end
3

There are 3 answers

0
KIDdAe On

Instead of [jsonResults isKindOfClass:[NSNull class]] you can simply do jsonResults == [NSNull null]

3
trojanfoe On

You are not checking if response is NSNull. My approach would be to test for what you want, not what you don't want:

NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if (jsonResults) {    // This won't be NSNull, it will be nil on error
    NSDictionary *response = jsonResults[@"response"];
    if ([response isKindOfClass:[NSDictionary class]]) {
        NSNumber *insertId = response[@"insert_id"];    // Assumption
        if ([insertId isKindOfClass:[NSNumber class]]) {
            // Print value
        }
    }
} else {
    // Report error
}

In reality you need to know what values are optional and what values can be of different types, as you don't want to code the whole module using isKindOfClass.

20
Ketan Parmar On

try like this,

  if (![jsonResults isKindOfClass:[NSNull class]] || !(jsonResults==nil)) {

    if (![jsonResults[@"response"][@"insert_id"]isKindOfClass:[NSNull class]]) {

        //Do your task here
    }

}

It is because if your jsonResults is null then it can't check for [jsonResults[@"response"][@"insert_id"] !!

Update :

   if (!(jsonResults==nil)) {

    if (![jsonResults[@"response"][@"insert_id"]isKindOfClass:[NSNull class]]) {

        //Do your task here
    }

}

No need to check for NSNull for jsonResults. It only can be nil and objects contains by that jsonResults can be NSNull.

Hope this will help :)