我可以让 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 获取 NSData,而不是让它转换为 UIImage
使用 AFNetworking 自动刷新令牌的最佳解决方案?