3

我们目前正在为我们的 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 客户端之一之前:不幸的是,它们似乎都不受支持和/或过时,包括微软列出的官方客户端。

4

2 回答 2

1

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

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

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

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

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

于 2013-08-08T17:26:04.170 回答
0

在不深入了解 OAuth 为何执行您所描述的操作的细节的情况下,这就是我将如何处理这个问题。

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

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

于 2013-09-19T19:13:57.643 回答