Checking a null value in Objective-C that has been returned from a JSON string

IosObjective CJson

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

<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.)

Solution 2 - Ios

Here is the example with the cast:

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

Solution 3 - Ios

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);  
   
}

Solution 4 - Ios

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

Solution 5 - Ios

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

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

It doesn't produce a warning :)

Solution 6 - Ios

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

Solution 7 - Ios

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

Solution 8 - Ios

In Swift you can do:

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

Solution 9 - Ios

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/

Solution 10 - Ios

Try this:

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

Solution 11 - Ios

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
}

Solution 12 - Ios

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

Solution 13 - Ios

I use this:

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

Solution 14 - Ios

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 = @"";

Solution 15 - Ios

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChrisView Question on Stackoverflow
Solution 1 - IosWevahView Answer on Stackoverflow
Solution 2 - IosFleaView Answer on Stackoverflow
Solution 3 - IosNitin GohelView Answer on Stackoverflow
Solution 4 - IosKyle CView Answer on Stackoverflow
Solution 5 - IoskjoelbroView Answer on Stackoverflow
Solution 6 - IosBrianView Answer on Stackoverflow
Solution 7 - IosYunus Nedim MehelView Answer on Stackoverflow
Solution 8 - IosSegevView Answer on Stackoverflow
Solution 9 - IosMarin TodorovView Answer on Stackoverflow
Solution 10 - IosMritunjayView Answer on Stackoverflow
Solution 11 - Iosuser5930025View Answer on Stackoverflow
Solution 12 - IosGajendra K ChauhanView Answer on Stackoverflow
Solution 13 - IosCarles EstevadeordalView Answer on Stackoverflow
Solution 14 - IosChandni - SystematixView Answer on Stackoverflow
Solution 15 - IosRahul NarangView Answer on Stackoverflow