459
votes

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

16
(Just for anyone googling to here. Note that this is a very old question. SaintMacintosh answer below is the state of the art, it is five years ahead of this QA. Hope it helps.)Fattie
Actually, Andy Dent's answer also gives the state of the art, and more context. And it did this earlier than SaintMacintosh. Do yourself a favor an scroll down a little more.Peter Kämpf
He uses: keysByName[test] != nil the != nil check is redundant and IMHO less readable. I just wanted to share the TL;DR version for people looking the syntax.Andrew Hoos
I agree with @SaintMacintosh. his answer is much more succinct.Steve Schwarcz
If you wish to check if the NSDictionary contains any key (non-specific) you should use [dictionary allKeys].count == 0 If the count is 0 there are no keys in the NSDictionary.Aleksander Azizi

16 Answers

773
votes

objectForKey will return nil if a key doesn't exist.

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

or

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

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.

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

When using JSON dictionaries:

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

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

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

5
votes

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
5
votes

Using Swift, it would be:

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

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"];
3
votes

For checking existence of key in NSDictionary:

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

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]) { }
2
votes

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
}
1
votes

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
}
1
votes

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;

}

0
votes
if ([MyDictionary objectForKey:MyKey]) {
      // "Key Exist"
} 
0
votes
if ( [dictionary[@"data"][@"action"] isKindOfClass:NSNull.class ] ){
   //do something if doesn't exist
}

This is for nested dictionary structure