22

我们在我们的移动应用程序中使用 AFNetworking 并且很多时候我们会返回 JSON,其中某些值具有 null。

我厌倦了以下操作。

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

如果 JSON 响应中的值为 null,我们可以做些什么来让 AFNetworking 自动将对象设置为 nil 或将数字设置为 0?

4

6 回答 6

31

您可以在 AFHTTPSessionManager 响应序列化程序中将标志 setRemovesKeysWithNullValues 设置为 YES:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];
于 2015-03-13T15:32:50.823 回答
21

这实际上是不可能的,因为字典不能包含nil作为键的对象。为了获得您想要的行为,必须完全忽略密钥,这以自己的方式是不可取的。

假设您无法控制正在接收的数据并且不知道 JSON 中存在哪些键。如果您想将它们全部列出,或者将它们显示在表格中,并且空对象的键被排除在字典之外,那么您将看到一个不正确的列表。

NSNull是 Cocoa 集合的“无”占位符,这就是在这种情况下使用它的原因。

您可以使用宏使您的打字更容易:

#define nilOrJSONObjectForKey(JSON_, KEY_) [[JSON_ objectForKey:KEY_] isKindOfClass:[NSNull class]] ? nil : [JSON_ objectForKey:KEY_]

nickname = nilOrJSONObjectForKey(json, @"nickname");
于 2012-05-22T01:05:43.780 回答
2

DV_ 的回答非常适合 AFHTTPSessionManager。但是,如果您使用的是 AFHTTPRequestOperation 而不是管理器,请尝试以下操作:

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
serializer.removesKeysWithNullValues = YES;
op.responseSerializer = serializer;
于 2015-04-10T11:12:41.307 回答
2

有一个名为 Minced https://github.com/hyperoslo/Minced的漂亮 cocoapod 可以帮助您处理来自 JSON 响应的 NULL。它放置空字符串而不是 NULL。

于 2015-10-28T17:08:57.180 回答
1

如果您将默认的 NSJSONSerialization 替换为 SBJSON,它将解决您的问题。

SBJSON 使对象为零,而不是 NSJSONSerialization 选择“null”

查看您可以使用的不同 JSON 解析器的要求。 https://github.com/AFNetworking/AFNetworking#requirements

于 2012-05-22T00:44:13.840 回答
0

您可以在此功能上自定义 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;

}

于 2017-06-14T07:23:43.750 回答