[objective-c] How to check if an NSDictionary or NSMutableDictionary contains a key?

I need to check if an dict has a key or not. How?

This question is related to objective-c foundation

The answer is


For checking existence of key in NSDictionary:

if([dictionary objectForKey:@"Replace your key here"] != nil)
    NSLog(@"Key Exists");
else
    NSLog(@"Key not Exists");

Because nil cannot be stored in Foundation data structures NSNull is sometimes to represent a nil. Because NSNull is a singleton object you can check to see if NSNull is the value stored in dictionary by using direct pointer comparison:

if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }

Using Swift, it would be:

if myDic[KEY] != nil {
    // key exists
}

Solution for swift 4.2

So, if you just want to answer the question whether the dictionary contains the key, ask:

let keyExists = dict[key] != nil

If you want the value and you know the dictionary contains the key, say:

let val = dict[key]!

But if, as usually happens, you don't know it contains the key - you want to fetch it and use it, but only if it exists - then use something like if let:

if let val = dict[key] {
    // now val is not nil and the Optional has been unwrapped, so use it
}

One very nasty gotcha which just wasted a bit of my time debugging - you may find yourself prompted by auto-complete to try using doesContain which seems to work.

Except, doesContain uses an id comparison instead of the hash comparison used by objectForKey so if you have a dictionary with string keys it will return NO to a doesContain.

NSMutableDictionary* keysByName = [[NSMutableDictionary alloc] init];
keysByName[@"fred"] = @1;
NSString* test = @"fred";

if ([keysByName objectForKey:test] != nil)
    NSLog(@"\nit works for key lookups");  // OK
else
    NSLog(@"\nsod it");

if (keysByName[test] != nil)
    NSLog(@"\nit works for key lookups using indexed syntax");  // OK
else
    NSLog(@"\nsod it");

if ([keysByName doesContain:@"fred"])
    NSLog(@"\n doesContain works literally");
else
    NSLog(@"\nsod it");  // this one fails because of id comparison used by doesContain

if ([mydict objectForKey:@"mykey"]) {
    // key exists.
}
else
{
    // ...
}

Yes. This kind of errors are very common and lead to app crash. So I use to add NSDictionary in each project as below:

//.h file code :

@interface NSDictionary (AppDictionary)

- (id)objectForKeyNotNull : (id)key;

@end

//.m file code is as below

#import "NSDictionary+WKDictionary.h"

@implementation NSDictionary (WKDictionary)

 - (id)objectForKeyNotNull:(id)key {

    id object = [self objectForKey:key];
    if (object == [NSNull null])
     return nil;

    return object;
 }

@end

In code you can use as below:

NSStrting *testString = [dict objectForKeyNotNull:@"blah"];

As Adirael suggested objectForKey to check key existance but When you call objectForKeyin nullable dictionary, app gets crashed so I fixed this from following way.

- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;

if (dictionary && (object != [NSNull null])) {
    self.name = [dictionary objectForKey:@"name"];
    self.age = [dictionary objectForKey:@"age"];
}
return self;

}


if ([MyDictionary objectForKey:MyKey]) {
      // "Key Exist"
} 

I'd suggest you store the result of the lookup in a temp variable, test if the temp variable is nil and then use it. That way you don't look the same object up twice:

id obj = [dict objectForKey:@"blah"];

if (obj) {
   // use obj
} else {
   // Do something else
}

More recent versions of Objective-C and Clang have a modern syntax for this:

if (myDictionary[myKey]) {

}

You do not have to check for equality with nil, because only non-nil Objective-C objects can be stored in dictionaries(or arrays). And all Objective-C objects are truthy values. Even @NO, @0, and [NSNull null] evaluate as true.

Edit: Swift is now a thing.

For Swift you would try something like the following

if let value = myDictionary[myKey] {

}

This syntax will only execute the if block if myKey is in the dict and if it is then the value is stored in the value variable. Note that this works for even falsey values like 0.


if ( [dictionary[@"data"][@"action"] isKindOfClass:NSNull.class ] ){
   //do something if doesn't exist
}

This is for nested dictionary structure


I like Fernandes' answer even though you ask for the obj twice.

This should also do (more or less the same as Martin's A).

id obj;

if ((obj=[dict objectForKey:@"blah"])) {
   // use obj
} else {
   // Do something else like creating the obj and add the kv pair to the dict
}

Martin's and this answer both work on iPad2 iOS 5.0.1 9A405


When using JSON dictionaries:

#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]

if( isNull( dict[@"my_key"] ) )
{
    // do stuff
}

if ([[dictionary allKeys] containsObject:key]) {
    // contains key
}

or

if ([dictionary objectForKey:key]) {
    // contains object
}