¿Puedo hacer que AFNetworking analice automáticamente NULL a cero?

Estamos utilizando AFNetworking en nuestra aplicación mobile y muchas veces haremos que JSON regrese y tenga valores nulos para algunos.

Me estoy cansando de hacer lo siguiente.

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

¿Algo que podamos hacer para que AFNetworking configure automágicamente objects a cero o numbers a 0 si el valor es nulo en la respuesta JSON?

Realmente no es posible, ya que el dictionary no puede contener nil como el object de una key. La key debería omitirse por completo para get el comportamiento que desea, lo que sería indeseable a su manera.

Suponga que no tenía control sobre los datos que estaba recibiendo y no sabía qué teclas estaban presentes en JSON. Si desea enumerarlos todos, o mostrarlos en una tabla, y las keys para los objects nulos quedaron fuera del dictionary, vería una list incorrecta.

NSNull es el marcador de position "nada" para las collections de Cacao, y es por eso que se usa en este caso.

Podría hacer que su tipeo sea 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"); 

Puede establecer el indicador setRemovesKeysWithNullValues ​​en YES en el serializador de respuesta AFHTTPSessionManager:

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

La respuesta de DV_ funciona muy bien para AFHTTPSessionManager. Pero si está utilizando AFHTTPRequestOperation en lugar del administrador, intente esto:

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

Si reemplaza la NSJSONSerialization por defecto con SBJSON, resolverá su problema.

SBJSON hace que los objects sean nulos en lugar de la opción de NSJSONSerialization de "nulo"

mira los requisitos para los diferentes analizadores JSON que puedes usar. https://github.com/AFNetworking/AFNetworking#requirements

Hay un hermoso cocoapod llamado Minced https://github.com/hyperoslo/Minced que puede hacer algo que lo ayude a manejar NULL desde la respuesta de JSON. En lugar de NULL, coloca una cadena vacía.

Puede AFNetworking personalizado en estas funciones. establecer cualquier valor pnetworkingeterminado en los objects 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; 

}