¿Puedo obtener afnetworking para analizar automáticamente null a nil?
-
12-12-2019 - |
Pregunta
Estamos usando AFNetworking en nuestra aplicación móvil y muchas veces que volveremos a regresar JSON que tiene 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"];
}
¿Algo que podamos hacer para hacer que AFNetworking configure automáticamente objetos a Nil o números a 0 si el valor es nulo en la respuesta JSON?
Solución
No es realmente posible, ya que el diccionario no puede contener nil
como el objeto para una clave.La clave tendría que ser dejada fuera completamente para obtener el comportamiento que querrías, lo que sería indeseable a su manera.
Supongamos que no tenía control sobre los datos que recibía y no sabía qué claves estaban presentes en el JSON.Si quisiera enumerarlos a todos, o mostrarlos en una tabla, y las llaves para los objetos nulos quedaron fuera del diccionario, estaría viendo una lista incorrecta.
NSNull
es el marcador de posición "nada" para las colecciones de cacao, y es por eso que se usa en este caso.
Podría hacer que su escritura 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");
Otros consejos
Puede establecer banderas setREMOVEESKEYYSWITHNULLUVALES a SÍ en el Serializador de respuesta AFHTTSESIONSIONMANOGER:
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];
dv_ funciona ideal para afhttpsessionmaager.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;
Hay una hermosa Cocoapod llamada picada https://github.com/hyperoslo/mince que puedeHaga algo que pueda ayudarlo a manejar NULL de la respuesta de JSON.En lugar de nulo, pone la cadena vacía.
Si reemplaza el NSJSSerialización predeterminado con SBJSON, resolverá su problema.
SBJSON HACE OBJETOS NIL En lugar de la elección de "NULL" de NSJSSERIALIZACIÓN
Consulte los requisitos para los diferentes parsers de JSON que puede usar. https://github.com/afnetworking/afnetworkinging#Requirements
Puede personalizar AFNetworking en estas funciones.Establezca cualquier valor predeterminado de los objetos que sea 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;
}