在 Swift 中映射具有相同顶层结构的各种 JSON 响应

Mapping a variety of JSON responses with the same top - level structure in Swift

我有各种各样的 JSON 响应,这些响应是我通过 Alamofire 从服务器返回的;下面包括两个:

1)

{
  "json" : {
    "harkUpdate" : {
      "more" : [
        {
          "unread-count" : {
            "last" : 1613507864973,
            "index" : {
              "graph" : {
                "graph" : "\/ship\/~dopzod\/urbit-help",
                "index" : "\/"
              }
            }
          }
        },
        {
          "seen-index" : {
            "index" : {
              "graph" : {
                "index" : "\/",
                "graph" : "\/ship\/~dopzod\/urbit-help"
              }
            },
            "time" : 1613507864973
          }
        }
      ]
    }
  },
  "response" : "diff",
  "id" : 3
}
    {
      "json" : {
        "graph-update" : {
          "keys" : [
            {
              "name" : "book-club-4717",
              "ship" : "sicdev-pilnup"
            },
            {
              "name" : "dm--locrev-finlys",
              "ship" : "haddef-sigwen"
            },
            {
              "name" : "smol-bibliotheca",
              "ship" : "dasfeb"
            },
            {
              "name" : "interface",
              "ship" : "bitpyx-dildus"
            },
            {
              "name" : "jobs-gigs",
              "ship" : "nibset-napwyn"
            },
            {
              "name" : "tlon-general",
              "ship" : "bolbex-fogdys"
            }
          ]
        }
      },
      "id" : 1,
      "response" : "diff"
    }

如您所见,它们都有一个 id、一个 responsejson 字段 - 但它们的实际 json 响应各不相同。

通常我会做的是使用 quicktype.io 之类的东西生成 类,或者使用那里的许多 ObjectMapping 框架之一。我试图在精神上不受阻碍的是,所有这些 json 响应都有一个名为“json”的字段,它具有不同的结构。我正在尝试弄清楚我可以为给定此结构的响应制作唯一 类。任何帮助表示赞赏。

你可以声明一个基本对象,它是 json 属性 将是一个符合 Codable 的通用类型。

struct JSON<T : Codable>: Codable {
    let json: T
    let id: Int
    let response: String
}

定义两个结构后,它们将代表第一个和第二个 json 对象。为简单起见,我将只定义代表第二个 JSON:

的对象
struct GraphUpdate: Codable {
    let graphUpdate: Keys

    enum CodingKeys: String, CodingKey {
        case graphUpdate = "graph-update"
    }
}

struct Keys: Codable {
    let keys: [Key]
}

struct Key: Codable {
    let name, ship: String
}

并且在尝试解码时,您必须指定要解码的对象:

let item = try? JSONDecoder().decode(JSON<GraphUpdate>.self, from: data)