objective-c - example - objective c networking library
¿Puedo hacer que AFNetworking analice automáticamente NULL a nil? (6)
Estamos utilizando AFNetworking en nuestra aplicación móvil y muchas veces haremos que JSON regrese, lo cual es nulo para algunos valores.
Me estoy cansando de hacer lo siguiente.
if ([json objectForKey:@"nickname"] isKindOfClass:[NSNull class]]) {
nickname = nil;
} else {
nickname = [json objectForKey:@"nickname"];
}
¿Podemos hacer algo para que AFNetworking establezca automáticamente los objetos en nulo o los números a 0 si el valor es nulo en la respuesta JSON?
Hay un hermoso cocoapod llamado Minced https://github.com/hyperoslo/Minced que puede hacer algo que puede ayudarte a manejar NULL desde la respuesta de JSON. En lugar de NULL pone una cadena vacía.
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;
No es realmente posible, ya que el diccionario no puede contener nil
como objeto para una clave. La clave debería quedar completamente fuera para obtener 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é claves estaban presentes en el JSON. Si quisiera enumerarlos todos, o mostrarlos en una tabla, y las claves para los objetos nulos no se incluyeran en el diccionario, vería una lista incorrecta.
NSNull
es el marcador de posición de "nada" para las colecciones de Cocoa, y es por eso que se usa en este caso.
Podrías hacer tu escritura 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 flag setRemovesKeysWithNullValues en YES en el serializador de respuestas AFHTTPSessionManager:
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];
Puede personalizar el AFNetworking en estas funciones. establecer cualquier valor predeterminado para los 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;
}
Si reemplaza la serialización NSJ predeterminada con SBJSON, se resolverá su problema.
SBJSON hace que los objetos sean nulos en lugar de la elección de NSJSONSerialization de "null"
mire los requisitos para los diferentes analizadores JSON que puede usar. https://github.com/AFNetworking/AFNetworking#requirements