我可以让 AFNetworking 自动将 NULL 解析为 nil 吗?

Posted

技术标签:

【中文标题】我可以让 AFNetworking 自动将 NULL 解析为 nil 吗?【英文标题】:Can I get AFNetworking to automatically parse NULL to nil? 【发布时间】:2012-05-22 00:37:39 【问题描述】:

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

我已经厌倦了以下操作。

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

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

【问题讨论】:

【参考方案1】:

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

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
[serializer setRemovesKeysWithNullValues:YES];
[manager setResponseSerializer:serializer];

【讨论】:

我比其他人更喜欢你的答案【参考方案2】:

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

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

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

您可以使用宏使您的打字更轻松:

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

nickname = nilOrJSONObjectForKey(json, @"nickname");

【讨论】:

我想这可能就是我要使用的,我的意思是宏。谢谢! 实际上我不知道为什么完全省略密钥是一件坏事?我宁愿做nickname = [json objectForKey:@"nickname"] 并且让它为空并且能够在其他地方说if(!nickname) @biarda:如果你想从字典中获取所有键的列表怎么办?你会得到一个不正确的答案——密钥存在于 JSON 中。 我不确定我是否曾经必须这样做,或者是否能想到我需要这样做的原因。 假设您在表格中显示整个字典,或者根本不知道可用的键。【参考方案3】:

DV_ 的回答非常适合 AFHTTPSessionManager。但是如果你使用的是 AFHTTPRequestOperation 而不是管理器,试试这个:

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
serializer.removesKeysWithNullValues = YES;
op.responseSerializer = serializer;

【讨论】:

有效。但是,我认为您的意思是:AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; 是的,我确实做到了。已编辑。谢谢【参考方案4】:

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

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

我刚试过这个,这似乎不是 SBJSON 的默认行为。如果我删除控制语句以检查是否为空,那么在尝试设置属性时会收到此错误[NSNull stringByDecodinghtmlEntities]【参考方案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;

【讨论】:

以上是关于我可以让 AFNetworking 自动将 NULL 解析为 nil 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AFNetworking 将数据发布到 Parse.com

使用 AFNetworking 进行 SSL 固定不起作用

直接从 AFNetworking 获取 NSData,而不是让它转换为 UIImage

使用 AFNetworking 自动刷新令牌的最佳解决方案?

iOS-AFNetworking3.0上传大量(1000张)图片到服务器

无法在 Today Extension 上使用 AFNetworking