How to check if NSDictionary key is NULL
I am trying to check if an object exists for a key next_max_id
in my JSON response dictionary. I've tried the following ways to check:
-
if ([[pagination objectForKey:@"next_max_id"] isKindOfClass:[NSNull class]]) ...
-
if ([pagination objectForKey:@"next_max_id"] == [NSNull class]) ...
-
if ([pagination objectForKey:@"next_max_id"]) ...
However, when the pagination dictionary is empty ie ( pagination = {};
), I get the following error messages:
-[NSNull objectForKey:]: unrecognized selector sent to instance ...
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull objectForKey:]: unrecognized selector sent to instance ...
How else can I check if an object, or rather a key, exists without crashing?
Updated: When the key next_max_id
exists internally pagination
, the JSON response will be like
"pagination": {
"next_url": "https://api.instagram.com/v1/tags/puppy/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&max_id=13872296",
"next_max_id": "13872296"
}
source to share
With the error you describe, pagination is not an NSDictionary, but the pagination itself is an NSNull object. So the first check before everything else was
if (pagination == [NSNull null]) ...
This will not happen if your JSON data contains "pagination": {}, but it will happen if your JSON data contains "pagination": null.
source to share
The actual problem is that pagination
- nil
, you cannot call any selectors over NSNull
. As you mentioned - the problem only occurs when the pagination
JSON is empty, so you get a null object.
So,
if (pagination && ![pagination isKindOfClass:[NSNull class]]) {
... // Do your things
}
if pagination is a valid object NSDictionary
, it objectForKey:
will return for a nonexistent key nil
.
source to share
Check the key exists and does not:
if([pagination objectForKey:@"next_max_id"] != nil) {
// exists
}
else {
// not exists
}
To check the key, there is a value null
if([pagination objectForKey:@"next_max_id"] == [NSNull null]) {
// {"next_max_id":null, ...}
}
else {
// not exists or values is not null
}
source to share
For example, I have created this demo that you can modify according to your needs.
NSDictionary *pagination =
[[NSDictionary alloc] initWithObjectsAndKeys:
@"https://api.instagram.com/v1/tags/puppy/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&max_id=13872296",@"next_url",
@"65765343",@"next_max_id", nil];
NSArray *array = [NSArray arrayWithArray:[pagination allKeys]];
if ( [array containsObject:@"next_max_id"] ) {
NSLog( @"%@",[pagination valueForKey:@"next_max_id"] );
} else {
NSLog(@"Key is null");
}
source to share
A very elegant solution is to write a swift category for NSDictionary.
For example:
#import "NSDictionary+safe.h"
@implementation NSDictionary (safeJSON)
- (id)safeObjectForKey:(NSString *)key {
id object = [self objectForKey:key];
if (object == [NSNull null]) {
return nil;
} else {
return object;
}
}
@end
This was also mentioned by rckoenes here .
source to share
- [NSNull objectForKey:]: unrecognized selector sent to the instance
The error is already in your hands.
When you call [pagination objectForKey:]
it calls-[NSNull objectForKey:]
Hence, pagination
NSNull
NOT NSDictionary
. NSNull has no method objectForKey:
to call. This is why you got the error:
unrecognized selector posted to the instance
You can check it out,
if ([pagination isKindOfClass:[NSDictionary class]]) {
id value =[pagination objectForKey:@"key"];
}
source to share