1

I have JSON response that potentially can contain objects. In my model objects i make this:

 _price3 = self.serverData[@"price3"];

I wanted to make something like:

 _price3 = self.serverData[@"price3"] ? self.serverData[@"price3"] : @"0";

Problem is, in such construction it will always evaluate true, because i guess is an object.

To prevent have in my properties i want to modify getter to variables, to check, where value is nsnull, and if it is, return something like @"0". Is that possible?

Evgeniy Kleban
  • 6,794
  • 13
  • 54
  • 107
  • 1
    The are are multiple possible solutions to handle both `nil` and `NSNull` (yes, you have to handle both). You can try http://stackoverflow.com/a/23610588/669586 for example. Or create a macro. – Sulthan Jan 03 '17 at 09:18

3 Answers3

3

[NSNull null] is a singleton object, which is often used in dictionaries or arrays where you'd want to use nil as a value, which is forbidden by Objective-C.

So you can just write

_price3 = self.serverData[@"price3"] == [NSNull null] ? @"0" : self.serverData[@"price3"];
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
  • @Glorfindlel great, that is good solution. But what exactly is [NSNull null]? – Evgeniy Kleban Jan 03 '17 at 09:17
  • @EvgeniyKleban In Obj-C arrays and dictionaries cannot contain `nil`. Therefore we have a special singleton object that is used instead of `nil` in arrays and dictionaries. – Sulthan Jan 03 '17 at 09:19
3

I am using this method in my every application.

-(NSString*)checkNullValidation:(NSString *)key {
    NSString *returnValue;
    if(key == (id)[NSNull null] || [key isEqual:[NSNull null]] || key == nil) {
        returnValue = @"";
    }
    else {
        returnValue = [NSString stringWithFormat:@"%@",key];
    }
    return returnValue;
}

So whenever I am parsing data, I do check like following e.g.,

NSDictionary *dictionaryTest = @{@"MyFirstKey":nil, @"MySecondKey":@"AwesomeValue"};
NSString *firstValue = [self checkNullValidation:[dictionaryTest valueForKey:@"MyFirstKey"]]; // It will be @"" instead of nil
NSString *secondValue = [self checkNullValidation:[dictionaryTest valueForKey:@"MySecondKey"]]; // It will be @"AwesomeValue"

So there are 0 percent chances that you will get nil or NULL and application will not crash. This thing will work even if your key is not present in response body.

If you want to use it on multiple screens, make one common handler class and add this as class method and use it. I almost used in all application and my apps never crashed because of such nil and NULL issues.

Pushkraj Lanjekar
  • 2,254
  • 1
  • 21
  • 34
1

You may use NSDictionary category like this:

@implementation NSDictionary (NilNull)

- (id)optionalObjectForKey:(id)key {
    return [self optionalObjectForKey:key defaultValue:nil];
}

- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue {
    id obj = [self objectForKey:key];
    return (obj == [NSNull null] || !obj) ? defaultValue : obj;
}

@end
rockhard
  • 349
  • 3
  • 8