2011-01-29 8 views
78

Tengo un objeto JSON que proviene de un servidor web.Comprobación de un valor nulo en Objective-C que se ha devuelto desde una cadena JSON

El registro es algo como esto:

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

Nota del teléfono está entrando como nulo si el usuario no introduce una.

Al asignar este valor a un NSString, en el NSLog está saliendo como <null>

voy a asignar la cadena como esta:

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

¿Cuál es la forma correcta de comprobar este valor <null>? Me impide guardar un NSDictionary.

He intentado usar las condiciones [myString length] y myString == nil y myString == NULL

Adicionalmente, donde es el mejor lugar en la documentación iOS para leer sobre esto?

+0

¿Cómo se asigna el valor al 'NSString'? – BoltClock

+0

Gracias BoltClock, he revisado la pregunta, consulte más arriba – Chris

+0

Muchas gracias por publicar esta pregunta. Me llamó la atención en este escenario durante todo un día. Agradecimiento especial a @Wevah – iCodeAtApple

Respuesta

181

<null> es cómo el NSNull singleton inicia sesión. Por lo tanto:

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

(existe el singleton porque no se puede añadir a nil clases de colección.)

+0

Perdí un ']' allí – BoltClock

+0

Saludos, tuve que lanzarlo para eliminar la advertencia, pero eso funcionó perfectamente – Chris

+0

@chris ¡Buena captura! Siempre las cosas pequeñas ... – Wevah

23

Aquí está el ejemplo con el elenco:

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

o si (tel == (NSString *) NSNull.null) {// hacer lógica aquí } No –

-6

Aquí también se puede hacer eso marcando la longitud de la cadena es decir

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

, si 'tel' es una instancia de' NSNull', esto generará una excepción. –

+0

sí, creo que tendremos que comprobar si es nulo o no también. Tenemos que considerar las condiciones anteriores también –

10

también se puede comprobar este lik cadena entrante e esta manera también: -

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

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

} 
+0

Su primera línea 'NSLog' es incorrecta ... debería decir que la cadena * está * vacía. ¿Y por qué imprimirlo en ese caso? – bdesham

+0

gracias por el asesoramiento e imprimo 'NSLog' solo por saber qué condición se hace realidad –

+0

@NitinGohel: gracias .. – iCodeAtApple

0

mejor sería si se adhieren a las mejores prácticas - es decir, utiliza un modelo de datos real para leer los datos JSON.

Tenga una mirada en JSONModel - es fácil de usar y que convertirá [NSNull nula] a * nula * Los valores de forma automática, por lo que podría hacer sus cheques como es habitual en Obj-C ¿Te gusta:

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

Tener un vistazo a la página de JSONModel: http://www.jsonmodel.com

Aquí también es un simple paseo a través de la creación de una aplicación basada en JSON: http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/

+0

¿Ese sitio JSONModel aún existe?No está en inglés, así que no estoy seguro, pero parece que no tiene mucho que ver con JSON. – smacdonald

9

Si se trata de una API "inestable", puede iterar a través de todas las claves para comprobar nulo. He creado una categoría para tratar con esto:

@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 
+0

mejor solución aquí – gbk

3

si tiene muchos atributos en JSON, utilizando if declaración para comprobar uno por uno es problemático. Lo que es peor es que el código sería feo y difícil de mantener.

Creo que el mejor enfoque es la creación de una categoría de 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 

después de importar esta categoría, se puede:

[json validatedValueForKey:key]; 
4

La mejor respuesta es lo que Aaron Hayman ha comentado por debajo de la aceptados respuesta:

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

No produce una advertencia :)

+1

Me gusta más, aunque es más prolijo :) –

2

por lo general lo hago de esta manera:

Assuma que tiene un modelo de datos para el usuario, y tiene una propiedad llamada NSString correo electrónico, tomaron de un diccionario JSON. Si se utiliza el campo de correo electrónico dentro de la aplicación, la conversión a cadena vacía evita posibles accidentes:

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

Prueba esto:

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

En Swift que puede hacer:

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

La pregunta es sobre Objective-C, no Swift. – JasonMArcher

+4

@JasonMArcher La respuesta todavía proporciona algún valor para aquellos que llegan a la pregunta desde una búsqueda en Google. Es una pregunta de 4 años después de todo. –

+0

Gracias. Me funcionó rápido. –

0

I Probé mucho método, pero nada funcionó. Finalmente esto funcionó para mí.

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

if ([usernameValue isEqual:@"(null)"]) 
{ 
    // str is null 
} 
0
if([tel isEqual:[NSNull null]]) 
{ 
    //do something when value is null 
} 
+0

Genera una advertencia: ** _ Tipos de punteros incompatibles que envían 'NSNull * _Nonnull' al parámetro de tipo 'Clase' _ ** –

0

Yo uso este:

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

si estamos recibiendo valor nulo como entonces lo podemos comprobar con fragmento de código a continuación.

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