How to safely work with NSDictionary that may have empty values or may not have a key

No comments on How to safely work with NSDictionary that may have empty values or may not have a key

Written by

in

Dictionary_2x

NSDictionary sometimes can contain a key with empty values or even may not contain a key, that we expect to have. This is a very common problem, when you work with server APIs and parse network JSON responses to a NSDictionary. In this post I will describe how to safely work with NSDictionary that may have empty values or may not have a key.

The method objectForKey will return nil, if there is no a key, a key doesn’t exist in a dictionary.

You can’t add nil to a NSDictionary. NSDictionary will throw an NSInvalidArgumentException if you attempt to insert a nil value. You would have to use [NSNull null] instead. NSNull is something called nothing, while nil is simply nothing.

Checks that value for key is not empty.

if (dic[@"key"] != (id)[NSNull null]) {
}

But if a dic doesn’t contain a key, you will enter to the body of a condition dic[@”key”] != (id)[NSNull null].

For example, before taking integerValue from obj, you must be sure, that it is not [NSNull null]:

id obj = dic[@"key"];
if (obj != (id)[NSNull null]) {
   cityId = [obj integerValue];
}

Checks that the key exists, but value for it can still be empty.

if (dic[@"key"] != nil) {
}

So the optimal check while reading NSDictionary is this, where key is “key”

id obj = dic[@"key"];
if ((obj != nil) && (obj != (id)[NSNull null])) {
}

You can’t add nil to a NSDictionary. So you have to check, that your object is not nil before adding:

if (obj != nil) {
   NSDictionary *dic = @{@"key":obj};
}

But you can add [NSNull null]:

id obj = [NSNull null];
NSDictionary *dic = @{@"key":obj};

Version of code, where you check if dictionary entry exists and not empty:

id obj = dic[@"key"];
if ( obj != nil ) {
    if ( obj != (id)[NSNull null] ) {
        // Use obj to get data
    }
    else {
        NSLog(@"Warning! ClassName: key section is empty.");
    }
}
else {
    NSLog(@"Warning! ClassName: key section is not found.");
}

I have created a NSDictionary category that has a method to check if a key exists and value is not empty:

#import "NSDictionary+CheckKey.h"

@implementation NSDictionary (CheckKey)


- (BOOL)checkKey:(NSString *)key className:(NSString *)className
{
    BOOL success = NO;
    id obj = self[key];
    if ( obj != nil ) {
        if ( obj != (id)[NSNull null] ) {
            success = YES;
        }
        else {
            NSLog(@"Warning! %@: %@ section is empty.", className, key);
        }
    }
    else {
        NSLog(@"Warning! %@: %@ section is not found.", className, key);
    }
    
    return success;
}


@end

This is an example, how to use it:

if ([dic checkKey:@"key" className:NSStringFromClass(self.class)]) {
    self.object = dic[@"key"];
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *