【问题标题】:JSONModel and ODataJSONModel 和 OData
【发布时间】:2013-09-20 03:13:57
【问题描述】:

我们目前正在为我们的 iOS 应用评估 JSONModel 并且到目前为止非常喜欢它。问题是,我们必须处理一个OData API,这往往会使一些地方的事情变得过于复杂。例如,当返回实体列表时,我能想到的所有 API 都会返回如下简单的内容:

{
  items: [
    { id => 123, name => 'foo' },
    { id => 124, name => 'bar' },
    { id => 125, name => 'baz' },
  ]
}

不幸的是,OData 给了我更多类似的东西:

{
  d: {
    results: [
      { Item => { id => 123, name => 'foo' } },
      { Item => { id => 124, name => 'bar' } },
      { Item => { id => 125, name => 'baz' } },
    ]
  }
}

“d”是我最小的问题(因为我们可以将其解析掉)。但是我不知道如何处理列表中的每个项目都包装在以项目类型作为键的哈希中的事实,因此通过 NSArray 的 JSONModel 关系不起作用。我可能会像这样为我的 Item 定义 JSONKeyMapper:

@"Item.id"   : @"id",
@"Item.name" : @"name"

但 OData 标准仅在有多个项目时将项目包装在自己的哈希结构中。例如,当仅从 OData API 获取单个项目时,我得到(如预期的那样):

{
  d: {
    results: {
      id => 123, 
      name => 'foo'
    }
  }
}

:-(

关于如何处理这个问题的任何想法?在有人推荐两个主要的 OData iOS 客户端之一之前:不幸的是,它们似乎都不受支持和/或过时,包括 Microsoft 列出的官方客户端。

【问题讨论】:

    标签: ios objective-c odata jsonmodel


    【解决方案1】:

    可能会回答您的问题的仅供参考:

    您发布的 JSON 是 OData 的旧 JSON 格式(现在通常称为“JSON Verbose”)。事实上,当 OData 被 OASIS 正式标准化后,它就会完全消失。

    我们替换这种旧格式的部分原因正是您在这里遇到的:它很难使用。

    如果您正在与之交谈的 OData 服务支持第 3 版 OData 协议,则请求“application/json”应该返回新的 JSON 格式。您可以更明确地要求“application/json;odata=minimalmetadata”。新的 JSON 格式没有任何“d”包装,其结构类似于您在问题顶部所期望的 JSON。

    如果您正在与之交谈的服务不支持 V3,并且您自己无法控制该服务,我会将其留给其他人来帮助您解决此问题所需的 Objective-C。如果您确实控制了服务(或者可以唠叨控制服务的人),我建议您更新服务以支持 V3。

    【讨论】:

    • 感谢您的洞察力,珍!
    • 不幸的是,AFAICT OData v3 仍然将扩展属性包装到它们各自的哈希结构中,这确实使得使用 JSONModel 甚至 RestKit 等标准 ORM 库变得困难。太糟糕了,几乎所有主要语言都有可用的 OData 参考实现,而官方 iOS 客户端库甚至无法与最新的 iOS 版本编译,这是我上次检查的时候。
    • 我认为你错了。 OData v3将扩展属性包装到它们自己的哈希结构中。我刚刚运行了下面的教程,它就像一个魅力。漂亮干净的 JSON。 asp.net/web-api/overview/odata-support-in-aspnet-web-api/…
    【解决方案2】:

    在不深入了解 OAuth 为何按照您所描述的那样做的情况下,以下是我的处理方法。

    1. 使“结果”成为可选属性。
    2. 添加访问器方法 (比方说)“resultsBetter”来模拟一个新的只读属性 你的模型类
    3. 制作一个 -(id)resultsBetter 方法检查类型 第一次访问该方法并返回一个“结果”值 匹配 1 个结果的 JSONModel 实例,或具有更多结果的数组 JSONModel 实例(或者如果您只需要数组中的第一个 您也只能返回 1 个对象)...

    无论如何,我的观点是您不需要一次性解析所有内容。您也可以在自定义访问器方法中首次访问该属性时执行此操作。或者如果你真的想做一些时髦的设置,你也可以实现一个自定义的 initWithDictionary:error: 方法并在实例初始化结束时添加一些额外的逻辑。

    【讨论】:

    • 谢谢!值得庆幸的是,我们完全摆脱了 OData 膨胀,现在正在努力寻找更易于使用的 API,从而使我的问题过时。 ;-)
    猜你喜欢
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多