2012-05-22 14 views
22

Estamos utilizando AFNetworking en nuestra aplicación móvil y muchas veces haremos que JSON regrese con valores nulos.¿Puedo obtener AFNetworking para analizar automáticamente NULL a nil?

Me estoy cansando de hacer lo siguiente.

if ([json objectForKey:@"nickname"] isKindOfClass:[NSNull class]]) { 
    nickname = nil; 
} else { 
    nickname = [json objectForKey:@"nickname"]; 
} 

Cualquier cosa que podamos hacer para que AFNetworking automágicamente objetos del juego a cero o números a 0 si el valor es nulo en la respuesta JSON?

Respuesta

20

No es realmente posible, ya que el diccionario no puede contener nil como objeto de una clave. La clave debería dejarse de lado para obtener el comportamiento que desea, lo cual no sería deseable a su manera.

Supongamos que no tiene control sobre los datos que estaba recibiendo y no sabía qué claves estaban presentes en el JSON. Si quisiera enumerarlos todos, o mostrarlos en una tabla, y las claves para los objetos nulos no estaban en el diccionario, estaría viendo una lista incorrecta.

NSNull es el marcador de "nada" para las colecciones de Cocoa, y es por eso que se utiliza en este caso.

usted podría hacer su escribiendo un poco más fácil con una macro:

#define nilOrJSONObjectForKey(JSON_, KEY_) [[JSON_ objectForKey:KEY_] isKindOfClass:[NSNull class]] ? nil : [JSON_ objectForKey:KEY_] 

nickname = nilOrJSONObjectForKey(json, @"nickname"); 
+0

Creo que esto es probablemente lo que voy a hacer, me refiero al macro. ¡Gracias! – birarda

+0

En realidad, no estoy seguro de por qué no es bueno omitir la clave por completo. Prefiero hacer 'nickname = [json objectForKey: @" nickname "]' y que sea nulo y pueda decir 'if (! Nickname)' en otro lugar. – birarda

+0

@birarda: ¿Qué pasa si quieres pedirle al diccionario una lista de todas sus llaves? Recibirá una respuesta incorrecta: la clave existe en el JSON. –

1

Si reemplaza la NSJSONSerialización predeterminada con SBJSON, se solucionará su problema.

SBJSON hace que los objetos nil en lugar de la opción de "nulo"

vistazo a los requisitos para los diferentes analizadores JSON se pueden utilizar de NSJSONSerialization. https://github.com/AFNetworking/AFNetworking#requirements

+0

simplemente he intentado esto y que no parece ser el comportamiento predeterminado de SBJSON. Si elimino la instrucción de control para verificar si es nula, entonces obtengo este error '[NSNull stringByDecodingHTMLEntities]' cuando intento establecer la propiedad. – birarda

29

Es posible ajustar setRemovesKeysWithNullValues ​​bandera de SI en serializador respuesta AFHTTPSessionManager: Respuesta

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config]; 
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; 
[serializer setRemovesKeysWithNullValues:YES]; 
[manager setResponseSerializer:serializer]; 
+0

Me gustan más sus respuestas que las demás – Lolloz89

2

de DV_ funciona muy bien para AFHTTPSessionManager. Pero si está utilizando AFHTTPRequestOperation convierta en el gestor, intente esto:

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; 
serializer.removesKeysWithNullValues = YES; 
op.responseSerializer = serializer; 
+0

Works. Sin embargo, creo que se refería a: 'AFJSONResponseSerializer * serializer = [AFJSONResponseSerializer serializer];' –

+0

Sí, de hecho lo hice. Editado Gracias – gavdotnet

2

Hay una hermosa cocoapod llamada picada https://github.com/hyperoslo/Minced que puede hacer algo que puede ayudar a manejar NULL de respuesta JSON. En lugar de NULL pone cadena vacía.

0

Puede personalizar AFNetworking en estas funciones. establecer cualquier valor por defecto de objetos que es NULL

static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) { 
if ([JSONObject isKindOfClass:[NSArray class]]) { 
    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]]; 
    for (id value in (NSArray *)JSONObject) { 
     [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)]; 
    } 

    return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray]; 
} else if ([JSONObject isKindOfClass:[NSDictionary class]]) { 
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject]; 
    for (id <NSCopying> key in [(NSDictionary *)JSONObject allKeys]) { 
     id value = (NSDictionary *)JSONObject[key]; 
     if (!value || [value isEqual:[NSNull null]]) { 
      // custom code here 
      //[mutableDictionary removeObjectForKey:key]; 
      [mutableDictionary setObject:@"" forKey:key]; 
     } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) { 
      mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions); 
     } 
    } 

    return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary]; 
} 

return JSONObject; 

}