Перевірка нульового значення в Objective-C, яке було повернуто із рядка JSON


78

У мене є об'єкт JSON, який надходить з веб-сервера.

Журнал приблизно такий:

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

Зверніть увагу, що телефон надходить як нульовий, якщо користувач не вводить його.

При присвоєнні цього значення значення a NSString, NSLogвоно виходить як<null>

Я присвоюю рядок так:

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

Який правильний спосіб перевірити це <null>значення? Це заважає мені зберегти файл NSDictionary.

Я спробував використовувати умови [myString length]та myString == nilтаmyString == NULL

Крім того, де найкраще в документації для iOS прочитати це?

Відповіді:


189

<null>- це те, як реєструється одиночний NSNull. Так:

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

(Синглтон існує, оскільки ви не можете додавати nilдо класів колекцій.)


41
Якщо ви хочете зробити це без акторського складу, ви також можете спробувати:if ([tel isKindOfClass:[NSNull class]])
Аарон Хейман

ми можемо використовувати: if (object isEqual: [NSNull null]) {--logic here--}
Gajendra K Chauhan


10

Ви також можете перевірити цей вхідний рядок так само: -

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

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

}

Ваш перший NSLogрядок неправильний ... у ньому повинно бути вказано, що рядок порожній. І чому б ви друкували його в такому випадку?
bdesham

дякую за пораду, і я друкую NSLogза те, що я просто знав, який стан справдився
Нітін Гогель

9

Якщо ви маєте справу з "нестабільним" API, можливо, вам доведеться переглядати всі ключі, щоб перевірити наявність нуля. Я створив категорію для вирішення цього:

@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

4

Найкраща відповідь - це те, що прокоментував Аарон Хейман нижче прийнятої відповіді:

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

Це не видає попередження :)


3

якщо у вас багато атрибутів у json, використання ifоператора для їх перевірки по черзі є проблематичним. Ще гірше те, що код був би потворним і важким для обслуговування.

Я думаю, що кращий підхід - це створення категорії 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

після імпорту цієї категорії ви можете:

[json validatedValueForKey:key];

2

Зазвичай я роблю це так:

Assuma У мене є модель даних для користувача, і вона має властивість NSString під назвою електронна пошта, отриману з дикту JSON. Якщо всередині програми використовується поле електронної пошти, перетворення його в порожній рядок запобігає можливим збоям:

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

2

У Swift ви можете зробити:

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

Питання стосується Objective-C, а не Swift.
JasonMArcher

4
@JasonMArcher Відповідь все ж надає певне значення для тих, хто приходить на запитання з пошуку Google. Зрештою, це 4-річне питання.
Beau Nouvelle

0

Найкраще було б, якщо ви дотримуєтесь найкращих практик - тобто використовуєте реальну модель даних для читання даних JSON.

Подивіться на JSONModel - він простий у використанні, і він автоматично перетворить [NSNUll null] на * nil * значення, щоб ви могли робити свої перевірки, як зазвичай, у Obj-c, наприклад:

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

Погляньте на сторінку JSONModel: http://www.jsonmodel.com

Ось також просте керівництво для створення програми на основі JSON: http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/


Цей сайт JSONModel все ще існує? Це не англійською мовою, тому я не можу бути впевненим, але, схоже, це не пов’язано з JSON.
Stewart Macdonald

0

Я багато пробував метод, але нічого не працювало. Нарешті, це спрацювало для мене.

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

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




0

якщо ми отримуємо нульове значення, як тоді, ми можемо перевірити це за допомогою наведеного нижче фрагмента коду.

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

-6

Тут ви також можете це зробити, перевіривши довжину рядка, тобто

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

3
Ні, якщо telце екземпляр NSNull, це спричинить виняток.
Kurt Revis

так, я думаю, нам доведеться перевірити, чи є воно нульовим чи ні. Ми також повинні врахувати вищезазначені умови
Рахул Наранг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.