Posso obter AFNetworking de analisar automaticamente NULO nulo?
-
12-12-2019 - |
Pergunta
Estamos usando AFNetworking em nosso aplicativo para dispositivos móveis e, muitas vezes, teremos JSON voltar nula para alguns valores.
Eu estou ficando cansado de fazer o seguinte.
if ([json objectForKey:@"nickname"] isKindOfClass:[NSNull class]]) {
nickname = nil;
} else {
nickname = [json objectForKey:@"nickname"];
}
Nada podemos fazer para tornar AFNetworking automagicamente conjunto de objetos a zero ou números de 0 se o valor é nulo em resposta JSON?
Solução
Não é realmente possível, já que o dicionário não pode conter nil
como o objeto para uma tecla.A chave teriam que ser deixadas de lado, a fim de obter o comportamento que você quer, o que seria indesejável em sua própria maneira.
Suponha que você não tem controle sobre os dados que estavam recebendo e não sabia que as chaves estavam presentes no JSON.Se você quiser listar todos eles, ou apresentá-los em uma tabela, e as chaves para objetos nulos foram deixados de fora do dicionário, você estaria vendo uma lista incorreta.
NSNull
é o "nada" espaço reservado para Cacau coleções, e é por isso que ele é usado neste caso.
Você poderia fazer a sua digitação um pouco mais fácil com uma macro:
#define nilOrJSONObjectForKey(JSON_, KEY_) [[JSON_ objectForKey:KEY_] isKindOfClass:[NSNull class]] ? nil : [JSON_ objectForKey:KEY_]
nickname = nilOrJSONObjectForKey(json, @"nickname");
Outras dicas
Você pode definir o sinalizador de setRemovesKeysWithNullValues SIM em AFHTTPSessionManager resposta serializador:
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];
DV_ a resposta de grandes obras para a AFHTTPSessionManager.Mas se você estiver usando AFHTTPRequestOperation em vez de o gestor, tente isso:
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
serializer.removesKeysWithNullValues = YES;
op.responseSerializer = serializer;
Há uma bela cocoapod chamado Picada https://github.com/hyperoslo/Minced que pode fazer algo que pode ajudar você a lidar NULO de resposta JSON.Em vez de NULL, ele coloca a cadeia de caracteres vazia.
Se você substituir o padrão NSJSONSerialization com SBJSON isso vai resolver o seu problema.
SBJSON faz objetos nulo em vez de NSJSONSerialization a escolha de "nulo"
olhe os requisitos para os diferentes JSON analisadores você pode usar.https://github.com/AFNetworking/AFNetworking#requirements
Você pode personalizar AFNetworking neste funções.definir qualquer valor padrão para objetos de que é NULO
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;
}