Могу ли я получить AFNetworking для автоматического анализа NULL на нуль?
Мы используем AFNetworking в нашем мобильном приложении, и много раз у нас будет JSON, который имеет нулевое значение для некоторых значений.
Мне надоело делать следующее.
if ([json objectForKey:@"nickname"] isKindOfClass:[NSNull class]]) {
nickname = nil;
} else {
nickname = [json objectForKey:@"nickname"];
}
Все, что мы можем сделать, чтобы AFNetworking автоматически устанавливал объекты на nil или numbers на 0, если значение NUL в ответе JSON?
Ответы
Ответ 1
Это не реально, поскольку словарь не может содержать nil
как объект для ключа. Ключ должен быть полностью исключен, чтобы получить нужное поведение, что было бы нежелательным по-своему.
Предположим, что у вас не было контроля над данными, которые вы получали, и не знали, какие ключи присутствовали в JSON. Если вы хотите перечислить их все или отобразить в таблице, а ключи для нулевых объектов были исключены из словаря, вы увидите неправильный список.
NSNull
является "ничем" заполнителем для коллекций Cocoa и почему он используется в этом случае.
Вы можете сделать свой ввод немного проще с помощью макроса:
#define nilOrJSONObjectForKey(JSON_, KEY_) [[JSON_ objectForKey:KEY_] isKindOfClass:[NSNull class]] ? nil : [JSON_ objectForKey:KEY_]
nickname = nilOrJSONObjectForKey(json, @"nickname");
Ответ 2
Вы можете установить флаг setRemovesKeysWithNullValues в YES в сериализаторе ответов AFHTTPSessionManager:
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];
Ответ 3
Ответ DV_ отлично подходит для AFHTTPSessionManager. Но если вы используете AFHTTPRequestOperation вместо менеджера, попробуйте следующее:
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
serializer.removesKeysWithNullValues = YES;
op.responseSerializer = serializer;
Ответ 4
Существует один красивый cocoapod под названием Minced https://github.com/hyperoslo/Minced, который может сделать что-то, что может помочь вам обработать NULL из ответа JSON. Вместо NULL он помещает пустую строку.
Ответ 5
Если вы замените стандартную NSJSONSerialization на SBJSON, она решит вашу проблему.
SBJSON создает объекты nil вместо выбора NSJSONSerialization "null"
рассмотрите требования к различным анализаторам JSON, которые вы можете использовать.
https://github.com/AFNetworking/AFNetworking#requirements
Ответ 6
Вы можете настраивать AFNetworking при выполнении этих функций. установите любое значение по умолчанию для объектов, которые являются 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;
}