【问题标题】:Swift 4.1 Parse Portion of JSONSwift 4.1 解析 JSON 的部分
【发布时间】:2018-12-06 20:54:04
【问题描述】:

我刚接触 Swift,想利用 Decodable 功能,希望能得到一些帮助。

我正在使用的公共 API 在密钥下发出我想要的数据:'c',但它周围有一些元数据。例如:

{
  a: 1,
  b: 2,
  c: [{
      d: 3,
      e: 4
    },
    {
      d: 5,
      e: 6
    }
  ]
}

我创建了一个这样的结构:

struct Block: Decodable {
   d: Int?
   e: Int?
}

如上所述,我希望能够将数据解析为类型:[Block] 来自“c”下的数据,尽可能迅速(对不起),并希望有一种 4.1 的方式来实现这一点。

感谢您的宝贵时间!

【问题讨论】:

  • 所以你想省略 a: 1, b: 2?
  • @PiotrLabunski 是的。我只是想知道最好的方法。

标签: json swift parsing decodable


【解决方案1】:

我认为最简单(最快速)的方法就是创建两个结构

struct BlockResponse: Decodable {
  let c: [Block]
}

struct Block: Decodable {
  let d: Int?
  let e: Int?
}

然后

let result = try decoder.decode(BlockResponse.self, from: jsonResponse)

编辑: 你也可以像这里一样省略BlockResponse https://gist.github.com/sgr-ksmt/d3b79ed1504768f2058c5ea06dc93698

通过使用带有 keyPath 的扩展:

extension JSONDecoder {
  func decode<T: Decodable>(_ type: T.Type, from data: Data, keyPath: String) throws -> T {
      let toplevel = try JSONSerialization.jsonObject(with: data)
      if let nestedJson = (toplevel as AnyObject).value(forKeyPath: keyPath) {
          let nestedJsonData = try JSONSerialization.data(withJSONObject: nestedJson)
          return try decode(type, from: nestedJsonData)
      } else {
          throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Nested json not found for key path \"\(keyPath)\""))
      }
  }
}



try decoder.decode([Block].self, from: data, keyPath: "c")

【讨论】:

  • 谢谢,我的印象是结构必须完全匹配json格式,不知道你可以省略字段!
  • 这是真的最简单的方法吗?很多语言使这个脚很容易。为什么我要创建不必要的包装器来保存我的业务数据只是为了符合 API,即使我永远不会在应用程序代码中使用或使用该层次结构......它会增加浪费和不必要的复杂性项目。看来 Swift 会让你跨过这些障碍......
  • 您可以使用带有 keyPath 的版本而无需其他结构(请参阅编辑)。在我看来,您根本不应该向您的移动客户端发送不必要的数据。如果 API 不受您控制,您可以创建一个中间件来为移动客户端调整数据。
猜你喜欢
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2019-01-08
相关资源
最近更新 更多