【问题标题】:Consuming complex JSON API responses into NSObjects using NSKeyValueCoding使用 NSKeyValueCoding 将复杂的 JSON API 响应消耗到 NSObjects
【发布时间】:2012-09-10 15:02:22
【问题描述】:

博文SAVING JSON TO CORE DATA 提供了一些将JSON 响应转换为Core Data 实体的重要技巧。我想做的是更具体一点。我想获取 JSON 响应,并使用博客文章中的方法将对象转换为 NSObject,其属性表示响应对象。我遇到的问题是对象的嵌套属性。以这个 JSON 响应为例:

http://us.battle.net/api/d3/profile/rnystrom-1254/

使用博文中描述的方法,“name”和“level”等简单属性很容易转换为 NSString 和 NSNumber 对象。但是,在查看响应的更复杂部分时会出现问题:嵌套数组/字典。

我发现的唯一解决方案是手动编码查找和转换所有这些属性,我认为这是一种非常糟糕的做法。这是我正在做的事情的摘录:

    NSDictionary *skillsDictionary = json[@"skills"];
    if ([skillsDictionary isKindOfClass:[NSDictionary class]]) {
        NSArray *activeArray = skillsDictionary[@"active"];
        NSArray *passiveArray = skillsDictionary[@"passive"];

        NSMutableArray *mutActives = [NSMutableArray array];
        NSMutableArray *mutPassives = [NSMutableArray array];

        if ([activeArray isKindOfClass:[NSArray class]]) {
            [activeArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                if ([obj isKindOfClass:[NSDictionary class]]) {
                    NSDictionary *activeJSON = (NSDictionary*)obj;
                    D3Skill *skill = [D3Skill activeSkillFromJSON:activeJSON];
                    if (skill) {
                        [mutActives addObject:skill];
                    }
                }
            }];
        }

        if ([passiveArray isKindOfClass:[NSArray class]]) {
            [passiveArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                if ([obj isKindOfClass:[NSDictionary class]]) {
                    NSDictionary *passiveJSON = (NSDictionary*)obj;
                    D3Skill *skill = [D3Skill passiveSkillFromJSON:passiveJSON];
                    if (skill) {
                        [mutPassives addObject:skill];
                    }
                }
            }];
        }

        self.activeSkills = mutActives;
        self.passiveSkills = mutPassives;
    }

【问题讨论】:

    标签: iphone ios json nsobject key-value-coding


    【解决方案1】:

    我使用 SBJSON 库和 ASIHttpRequest 从我自己设计的 Web 服务中获取和使用 JSON,如果我正确理解您的问题,您只需要执行以下操作:

    NSString *responseJSONasString = [fetchRequest responseString]; 
    NSDictionary *itemResponseArray = [responseJSONasString JSONValue];
    

    SBJSON 库将为您完成转换为 NSObject,并使用 JSON 元素上的键值编码将它们放入数组/字典中,因此使用您提供的 JSON,我可以获得第一个英雄的名称:

    NSArray *heroes = [itemResponseArray objectForKey:@"heroes"];
    NSDictionary *firstHero = [heroes objectAtIndex:0];
    NSString *heroName = [firstHero objectForKey:"name"];
    

    SBJson 可以在这里找到:http://stig.github.com/json-framework/

    【讨论】:

    • 一个小提示,我注意到在尝试从 ASIHTTPRequest 获取 responseString 的 JSONValue 时出现错误。为了谨慎起见,我现在自己编码我的字符串: NSString *responseJSONasString = [[NSString alloc] initWithData:[fetchRequest responseData] encoding:NSUTF8StringEncoding]; NSDictionary *itemResponseArray = [responseJSONasString JSONValue]; [responseJSONasString 发布];
    【解决方案2】:

    BWJSONMatcher 是我在项目中使用的一个轻量级库,用于将 JSON 数据从 RESTful api 转换为我的业务数据模型。它是这样的:

    ...
    NSString *jsonString = @"{your-json-string}";
    YourValueObject *dataModel = [YourValueObject fromJSONString:jsonString];
    
    NSDictionary *jsonObject = @{your-json-object};
    YourValueObject *dataModel = [YourValueObject fromJSONObject:jsonObject];
    ...
    YourValueObject *dataModel = instance-of-your-value-object;
    NSString *jsonString = [dataModel toJSONString];
    NSDictionary *jsonObject = [dataModel toJSONObject];
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 2012-02-12
      相关资源
      最近更新 更多