【问题标题】:Objective-C DRY JSON Mapping and Object CreationObjective-C DRY JSON 映射和对象创建
【发布时间】:2011-06-25 06:49:16
【问题描述】:

我正在尝试将 JSON 信息动态映射到不同的对象中。但是我不知道如何控制整个指针的情况,因为我希望不会起作用。

到目前为止,我的方法是为每个对象创建一个字典,将变量指针映射到等效的 JSON 键。在我的 JSON 映射器中,我有一个方法 parseJSONFromDictionary:withObject,它应该遍历 SBJSON 的 JSONValue 返回的字典,并将适当的值分配给给定对象中的适当变量。

-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start{
    for (NSString *key in dict) {
        if ([[self.mappings objectForKey:key] isMemberOfClass:[NSString class]]) {
            start.[self.mappings objectForKey:key] = [[dict valueForKey:key] stringValue];
        }
    }
    return start;
}

mappings 是包含变量和 json 键的字典,dict 是从 json 解析器返回的内容。

最大的问题是我做不到start.[self.mappings objectForKey:key]。我对C不太了解,显然我对指针的了解也不够,那么我该如何创建这种系统呢?我知道这不是正确的方法,但是正确的方法是什么?我知道这是可以做到的,就像RestKit 所做的那样,但他们不支持 OAuth,所以很遗憾我不能使用他们可爱的框架。

我选择这条路线的原因是因为我正在使用的 API 目前处于 alpha 阶段。我希望能够轻松适应未来的任何变化,而无需重写许多代码行。我也想开始 DRY-ly 编程。我知道 JSON 解析非常重复,我想找到一种方法来减少开销。

感谢您的所有帮助!


编辑:我的问题似乎有些混乱。我不需要解析 JSON 的帮助。我已经在使用SBJSON。我不需要请求帮助,我已经在使用JDG's OAuthConsumer framework。我只能使用支持 OAuth 2.0 的框架。

我确实需要帮助弄清楚如何防止这种情况:

-(Class1 *)parseJsonForClass1:(NSString *)inputString {
    NSDictionary *outputDict = [inputString JSONValue];
    Class1 *instance1 = [self mapObjectsForClass1From:outputDict];
    return instance1;
}

-(Class2 *)parseJsonForClass2:(NSString *)inputString {
    NSDictionary *outputDict = [inputString JSONValue];
    Class2 *instance2 = [self mapObjectsForClass2From:outputDict];
    return instance2;
}

-(Class3 *)parseJsonForClass3:(NSString *)inputString {
    NSDictionary *outputDict = [inputString JSONValue];
    Class2 *instance3 = [self mapObjectsForClass3From:outputDict];
    return instance3;
}

-(Class1 *)mapObjectsForClass1From:(NSDictionary *)dict {
    Class1 *object1 = [[Class1 alloc] init];
    object1.name = [[dict valueForKey:@"name"] stringValue];
    object1.date = [[dict valueForKey:@"date"] stringValue];
    object1.objId = [[dict valueForKey:@"id"] intValue];

    return object1;
}

-(Class2 *)mapObjectsForClass2From:(NSDictionary *)dict {
    Class2 *object2 = [[Class2 alloc] init];
    object2.something = [[dict valueForKey:@"something"] stringValue];
    object2.title = [[dict valueForKey:@"title"] stringValue];
    object2.imageUrl = [[dict valueForKey:@"image_url"] stringValue];

    return object2;
}

-(Class3 *)mapObjectsForClass3From:(NSDictionary *)dict {
    Class3 *object3 = [[Class3 alloc] init];
    object3.foo = [[dict valueForKey:@"bar"] stringValue];
    object3.flag = [[dict valueForKey:@"is_member"] boolValue];
    object3.obj1 = [[Class1 alloc] init];
    object3.obj1 = [self mapOjectsForClass1From:[dict objectForKey:@"name1"]];

    return object3;
}

所以,如果您对如何将这些方法组合成一种方法有任何建议,请告诉我...

【问题讨论】:

  • 我看过 Restkit。我不喜欢它的所作所为,而且我仍然不喜欢。在我的生活中,我从未见过比 RestKit 循环膨胀对象更完美的内存分配曲线。

标签: iphone objective-c json ios dry


【解决方案1】:

还可以查看HTTPRiot,它负责处理大部分通信工作,异步处理连接等。这个带有 iOS 的Tutorial about JSON communications(Ruby 弯曲,但最小)展示了如何使用它;一些代码已经过时,但总体上可以通过。

【讨论】:

  • 我之前做过大量的 JSON 工作,所以我知道如何将 JSON 解析为对象。我只是想弄清楚如何不为我要获取的每个对象提供单独的功能。另外,我需要使用 OAuth,所以我不能使用 HTTPRiot 或任何其他框架,除非他们已经内置了 OAuth(注意:我还没有找到一个这样做的)
  • 然后我支持另一个建议并研究 SBJSON(又名 JSON 框架)。它无缝管理 JSON 对象封送处理,同时让您管理底层 OAuth 管道。
  • 我已经在使用 SBJSON。这与解析 JSON 后的对象创建有关,而不是解析 JSON 本身。
【解决方案2】:

您可以使用 KVC。为 JSON 字典中要插入对象的每个值创建一个 setter,并使用 -setValue:forKey: 实际设置值,例如

-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start
{
    for (NSString *key in [dict allKeys]) 
    {
        NSString* propertyName = [[self mappings] objectForKey: key];
        [start setValue: [dict objectForKey: key] forKey: propertyName];
        // the above line will throw an exception if start does not have a set accessor for property
    }
    return start;
}

【讨论】:

  • 这可能正是我想要的!一旦我回到家里的 Mac,我一定会对此进行测试。
  • 与其编写额外的 setter 方法(我试图编写尽可能少的重复代码),不如这样的方法适合使用 setValue:forKey otakunozoku.com/objective-c-class-properties ??
  • 所以这绝对符合我正在寻找的路线。我的实现遇到了在函数中创建其他对象的问题,主要与在数组中创建的对象有关。一些 JSON 调用返回字典数组,然后需要将这些字典映射到不同的对象中......有什么地方可以指点我吗?
  • @MishieMoo:您绝对可以使用属性来提供您的设置器,但您可能仍需要手动编写实现代码以考虑其他对象数组的属性(大概您想向下递归并应用对数组中的对象进行相同类型的操作)。
【解决方案3】:

我实际上最近看到有人使用Objective Resources 这样做。虽然这是访问对象的好方法,但某些实现可能会变得混乱。而且无论您喜欢与否,您都必须使用服务器发送给您的所有内容。我现在要远离这个。

【讨论】:

    【解决方案4】:

    我知道这是一个旧线程,但想把它放在这里,https://github.com/mystcolor/JTObjectMapping 中的代码将有助于对象映射。在使用它之前,您需要准备好映射和自定义对象。 我在谷歌搜索中发现了这个....虽然没有使用过。需要尝试一下。

    【讨论】:

      猜你喜欢
      • 2011-08-09
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多