【问题标题】:Can I get AFNetworking to automatically parse NULL to nil?我可以让 AFNetworking 自动将 NULL 解析为 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?

【问题讨论】:

    标签: objective-c ios afnetworking


    【解决方案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;
      

      }

      【讨论】:

        猜你喜欢
        • 2017-08-23
        • 2018-06-26
        • 2019-11-25
        • 2017-11-04
        • 1970-01-01
        • 1970-01-01
        • 2010-12-29
        • 2012-11-03
        • 1970-01-01
        相关资源
        最近更新 更多