Расшифруйте JSON с помощью Swift 4 с помощью YouTube Analytics для вложенного неоключенного массива - PullRequest
0 голосов
/ 14 сентября 2018

Так что я столкнулся с некоторой проблемой при использовании API YouTube Analytics, который возвращает 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

Однако я не уверен, что даже доступ к значению является правильным.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

у вас должна быть идентичная структура, чтобы декодировать ответ в объект, и в качестве его JSON его [Key: Value] каждый ключ является строкой, которая указывает, что такое значение, поэтому значение может быть массивом илимассив массивов или другой объект, даже значение может быть любым в вашем случае

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

первый индекс, (types: youtubeAnalytics # resultTable), поэтому его следующий индекс String: String равен (columnHeader:), поэтому егоСтрока: этот объект также является ключом: значением, который имеет ключи name, 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
0 голосов
/ 14 сентября 2018
"rows": [
    [
        6
    ]
]

У вас есть массив внутри массива, поэтому пишите

let rows: [[Int]]

вместо

let rows: [Row]

, поскольку класс требует словарь, поскольку у класса есть его именаиспользует для ссылки на значения.Это было бы правильно с:

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

"6", так как вы пытались декодировать его в String?, а не Int, который API дал вам с 6.

Вы можете получить доступ к данным в строках, как обычно:

response.rows[0][0]

Для получения дополнительных способов доступа к массиву вы можете работать через
https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

Совет: Вы можете использовать приложение.quicktype.io, чтобы немедленно получить структуру для данного json.

...