
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"];
}