79

I have a JSON object that is coming from a webserver.

The log is something like this:

{          
   "status":"success",
   "UserID":15,
   "Name":"John",
   "DisplayName":"John",
   "Surname":"Smith",
   "Email":"email",
   "Telephone":null,
   "FullAccount":"true"
}

Note the Telephone is coming in as null if the user doesn't enter one.

When assigning this value to a NSString, in the NSLog it's coming out as <null>

I am assigning the string like this:

NSString *tel = [jsonDictionary valueForKey:@"Telephone"];

What is the correct way to check this <null> value? It's preventing me from saving a NSDictionary.

I have tried using the conditions [myString length] and myString == nil and myString == NULL

Additionally where is the best place in the iOS documentation to read up on this?

0

15 Answers 15

190

<null> is how the NSNull singleton logs. So:

if (tel == (id)[NSNull null]) {
    // tel is null
}

(The singleton exists because you can't add nil to collection classes.)

Sign up to request clarification or add additional context in comments.

2 Comments

If you want to do it without the cast, you can also try: if ([tel isKindOfClass:[NSNull class]])
we can use: if (object isEqual:[NSNull null]) {--logic here-- }
24

Here is the example with the cast:

if (tel == (NSString *)[NSNull null])
{
   // do logic here
}

1 Comment

or if (tel == (NSString *)NSNull.null) { // do logic here }
10

you can also check this Incoming String like this way also:-

if(tel==(id) [NSNull null] || [tel length]==0 || [tel isEqualToString:@""])
{
    NSlog(@"Print check log");
}
else
{  

    NSlog(@Printcheck log %@",tel);  

}

2 Comments

Your first NSLog line is incorrect… it should say that the string is empty. And why would you print it in that case?
thanks for advice and i print NSLog for just knowing which condition become true
9

If you are dealing with an "unstable" API, you may want to iterate through all the keys to check for null. I created a category to deal with this:

@interface NSDictionary (Safe)
-(NSDictionary *)removeNullValues;
@end

@implementation NSDictionary (Safe)

-(NSDictionary *)removeNullValues
{
    NSMutableDictionary *mutDictionary = [self mutableCopy];
    NSMutableArray *keysToDelete = [NSMutableArray array];
    [mutDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (obj == [NSNull null]) 
        {
            [keysToDelete addObject:key];
        }
    }];
    [mutDictinary removeObjectsForKeys:keysToDelete];
    return [mutDictinary copy];
}
@end

Comments

4

The best answer is what Aaron Hayman has commented below the accepted answer:

if ([tel isKindOfClass:[NSNull class]])

It doesn't produce a warning :)

Comments

3

if you have many attributes in json, using if statement to check them one by one is troublesome. What even worse is that the code would be ugly and hard to maintain.

I think the better approach is creating a category of NSDictionary:

// NSDictionary+AwesomeDictionary.h

#import <Foundation/Foundation.h>

@interface NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key;
@end

// NSDictionary+AwesomeDictionary.m

#import "NSDictionary+AwesomeDictionary.h"

@implementation NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key {
    id value = [self valueForKey:key];
    if (value == [NSNull null]) {
        value = nil;
    }
    return value;
}
@end

after importing this category, you can:

[json validatedValueForKey:key];

Comments

2

I usually do it like this:

Assuma I have a data model for the user, and it has an NSString property called email, fetched from a JSON dict. If the email field is used inside the application, converting it to empty string prevents possible crashes:

- (id)initWithJSONDictionary:(NSDictionary *)dictionary{

    //Initializer, other properties etc...

    id usersmail = [[dictionary objectForKey:@"email"] copy];
    _email = ( usersmail && usersmail != (id)[NSNull null] )? [usersmail copy] : [[NSString      alloc]initWithString:@""];
}

Comments

2

In Swift you can do:

let value: AnyObject? = xyz.objectForKey("xyz")    
if value as NSObject == NSNull() {
    // value is null
    }

2 Comments

Question is about Objective-C, not Swift.
@JasonMArcher The answer still provides some value for those coming to the question from a google search. It's a 4 year old question after all.
0

Best would be if you stick to best practices - i.e. use a real data model to read JSON data.

Have a look at JSONModel - it's easy to use and it will convert [NSNUll null] to * nil * values for you automatically, so you could do your checks as usual in Obj-c like:

if (mymodel.Telephone==nil) {
  //telephone number was not provided, do something here 
}

Have a look at JSONModel's page: http://www.jsonmodel.com

Here's also a simple walk-through for creating a JSON based app: http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/

1 Comment

Does that JSONModel site still exist? It's not in English so I can't be sure, but it doesn't look like it has much to do with JSON.
0

I tried a lot method, but nothing worked. Finally this worked for me.

NSString *usernameValue = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] valueForKey:@"usernameKey"]];

if ([usernameValue isEqual:@"(null)"])
{
     // str is null
}

Comments

0
if([tel isEqual:[NSNull null]])
{
   //do something when value is null
}

1 Comment

Generates a Warning: Incompatible pointer types sending 'NSNull * _Nonnull' to parameter of type 'Class'
0

Try this:

if (tel == (NSString *)[NSNull null] || tel.length==0)
{
    // do logic here
}

Comments

0

I use this:

#define NULL_TO_NIL(obj) ({ __typeof__ (obj) __obj = (obj); __obj == [NSNull null] ? nil : obj; }) 

2 Comments

could you guide how we can achieve the same in swift?
Hi @AmrAngry, I did not see your message, in swift there is a much better and sophisticated way to use response JSON objects using codable protocol on what is called a DTO: hackingwithswift.com/example-code/language/… Then you can get a struct or class with the objects you want, you can set coding keys so the variables do not have to have the same name than in the JSON object.
0

if we are getting null value like then we can check it with below code snippet.

 if(![[dictTripData objectForKey:@"mob_no"] isKindOfClass:[NSNull class]])
      strPsngrMobileNo = [dictTripData objectForKey:@"mobile_number"];
  else
           strPsngrMobileNo = @"";

Comments

-6

Here you can also do that by checking the length of the string i.e.

if(tel.length==0)
{
    //do some logic here
}

2 Comments

No, if tel is an instance of NSNull, this will raise an exception.
yes i think we will have to check it's null or not also.We have to consider the above conditions also

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.