解码 JSON 使用 Swift 4 和 Youtube Analytics 嵌套的非键控数组

Decode JSON using Swift 4 with Youtube Analytics for nested unkeyed array

所以我在使用 Youtube 分析 API 时遇到了一些问题,returns JSON 如下所示:

{
 "kind": "youtubeAnalytics#resultTable",
 "columnHeaders": [
  {
   "name": "views",
   "columnType": "METRIC",
   "dataType": "INTEGER"
  }
 ],
 "rows": [
  [
   6
  ]
 ]
}

我需要访问值 6 吗?

我创建的用于访问此值的结构似乎不起作用,我认为这与访问未加密的数组有关。

struct Response: Decodable {
    let rows: [Row]?
}

struct Row: Decodable {
    let value: String?

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        value = try container.decodeIfPresent(String.self)
    }
}

然后访问值:

let jsonReturn = try JSONDecoder().decode(Response.self, from: data)
let row = jsonResult.rows![0]
let value = row.value

但是我不确定访问该值是否正确。

"rows": [
    [
        6
    ]
]

这里数组中有数组,所以写

let rows: [[Int]]

而不是

let rows: [Row]

,因为 class 需要字典,因为 class 具有用于引用值的名称。它本来是正确的:

"rows": [
    {
        "value": "6"
    {
]

"6" 因为你试图将它解码为 String?,而不是 api 给你的 Int 6.

您可以照常访问行中的数据:

response.rows[0][0]

有关访问数组的更多方法,您可以通过
https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

提示:您可以使用 app.quicktype.io 立即获取给定 json 的结构。

您需要具有相同的结构,以便将响应解码为对象,并且作为其 JSON 它的 [Key:Value] 每个键都是一个字符串,指示值是什么,因此值可以是一个数组或数组数组或另一个对象,甚至在您的情况下该值可以是任何东西

{
 "kind": "youtubeAnalytics#resultTable",
 "columnHeaders": [
  {
   "name": "views",
   "columnType": "METRIC",
   "dataType": "INTEGER"
  }
 ],
 "rows": [
  [
   6
  ]
 ]
}

第一个索引,(种类:youtubeAnalytics#resultTable)所以它的字符串:字符串值 下一个索引是 (columnHeader: ) 所以它的 String: 这个对象也是 key: value,它有键名、columnType、DataType 因此,如何解码此特定响应的最终值很简单,如下面的代码所示,它会让您了解如何考虑 JSON 并希望在未来解码

    struct ColumnHeader: Codable {
    var name: String?
    var columnType: String?
    var dataType: String?
}
struct response: Codable {
    var kind: String?
    var columnHeaders: [ColumnHeader?]
    var rows: [[Int]?]
}
// after we have the data and decode it you can access the object easily as the following,
let obj = ColumnHeader(name: "test", columnType: "test", dataType: "test")
let resp = response(kind: "test2", columnHeaders: [obj], rows: [[2,4],[4,5]])

resp.kind
resp.columnHeaders[0]?.name