json на стремительный объект - PullRequest
0 голосов
/ 01 февраля 2020

Я использую API, который возвращает ответ json, каждый раз, когда ответ выглядит немного по-другому (в зависимости от параметра, который я запускаю в API). как я могу преобразовать json в swift, используя JSONDecoder, если структура json слегка меняется каждый раз [нужное мне поле появляется во всех ответах, это просто некоторые другие поля rnadom, которые мне даже не нужны]

вот пример 2 ответов

{
  "id": "EN_DE00013180",
  "source": "global",
  "language": "en",
  "version": 1,
  "headword": {
    "text": "unexpectedly",
    "pronunciation": {
      "value": "ˌʌnɪkˈspɛktɪdli"
    },
    "pos": "adverb"
  },
  "senses": [
    {
      "id": "EN_SE00022038",
      "translations": {
        "br": {
          "text": "inesperadamente"
        },
        "dk": {
          "text": "uventet"
        },
        "es": {
          "text": "inesperadamente"
        },
        "fr": {
          "text": "à l'improviste"
        },
        "ja": {
          "text": "意外(いがい)にも",
          "alternative_scripts": {
            "romaji": "igai ni mo"
          }
        },
        "no": {
          "text": "uventet"
        },
        "sv": {
          "text": "oväntat"
        }
      },
      "examples": [
        {
          "text": "guests who arrived unexpectedly",
          "translations": {
            "br": {
              "text": "convidados que chegaram inesperadamente"
            },
            "dk": {
              "text": "gæster, som ankom uventet"
            },
            "es": {
              "text": "@@@@@"
            },
            "fr": {
              "text": "des invités qui sont arrivés à l'improviste"
            },
            "ja": {
              "text": "予想外にやってきた客",
              "alternative_scripts": {
                "romaji": "yosoogai ni yattekita kyaku"
              }
            },
            "no": {
              "text": "gjester som kom uventet"
            },
            "sv": {
              "text": "gäster som kom oväntat"
            }
          }
        }
      ]
    }
  ],
  "related_entries": [
    "EN_DE00013179"
  ]
}

вот второй

{
  "id": "EN_DE00013182",
  "source": "global",
  "language": "en",
  "version": 1,
  "headword": {
    "text": "unfairly",
    "pronunciation": {
      "value": "ʌnˈfɛərli"
    },
    "pos": "adverb"
  },
  "senses": [
    {
      "id": "EN_SE00022040",
      "translations": {
        "br": {
          "text": "injustamente"
        },
        "dk": {
          "text": "uretfærdigt"
        },
        "es": {
          "text": "injustamente"
        },
        "fr": [
          {
            "text": "de manière injuste/irrégulière"
          },
          {
            "text": "injustement"
          }
        ],
        "ja": {
          "text": "不公平(ふこうへい)に",
          "alternative_scripts": {
            "romaji": "fukoohee ni"
          }
        },
        "no": [
          {
            "text": "urettferdig"
          },
          {
            "text": "på urettferdig vis"
          }
        ],
        "sv": [
          {
            "text": "orättvist"
          },
          {
            "text": "oschyst"
          }
        ]
      },
      "examples": [
        {
          "text": "unfairly treated/criticized/punished",
          "translations": {
            "br": {
              "text": "injustamente tratado/criticada/punido"
            },
            "dk": {
              "text": "uretfærdigt behandlet/kritiseret/straffet"
            },
            "es": {
              "text": "@@@@@"
            },
            "fr": {
              "text": "traité de manière injuste / critiqué/puni injustement"
            },
            "ja": {
              "text": "不公平に扱われる / 批判される / 処罰される",
              "alternative_scripts": {
                "romaji": "fukoohee ni atsukawareru / hihan sareru / shobatsu sareru"
              }
            },
            "no": {
              "text": "urettferdig behandlet/kritisert/straffet"
            },
            "sv": {
              "text": "orättvist behandlad/kritiserad/bestraffad"
            }
          }
        },
        {
          "text": "a trial that was conducted unfairly",
          "translations": {
            "br": {
              "text": "um julgamento que foi conduzido injustamente"
            },
            "dk": {
              "text": "en retsag, der var udført uretfærdigt"
            },
            "es": {
              "text": "@@@@@"
            },
            "fr": {
              "text": "un procès qui a été instruit de manière irrégulière"
            },
            "ja": {
              "text": "不公平に行われた裁判",
              "alternative_scripts": {
                "romaji": "fukoohee ni okonawareta saiban"
              }
            },
            "no": {
              "text": "en rettssak som ble gjennomført på urettferdig vis"
            },
            "sv": {
              "text": "en rättegång som genomfördes på ett ohederligt sätt"
            }
          }
        }
      ]
    }
  ],
  "related_entries": [
    "EN_DE00013181"
  ]
}

1 Ответ

0 голосов
/ 01 февраля 2020

Гетерогенные типы в swift лучше всего представлены в виде перечисления с соответствующим значением. Quicktype.io может кодировать gen код структуры, способной для вас, в том числе для разнородных типов, если вы предоставите ему массив всех возможных случаев. www.quicktype.io

Вы должны быть осторожны с кодом gen, потому что он хорош только для данных, которые вы ему предоставляете, поэтому он не будет выводить необязательные параметры, если не пропущен регистр. Вы всегда должны go генерировать код и убедиться, что дополнительные опции объявлены правильно.

Вот код, который я получаю для вашего примера (обратите внимание на перечисление)

// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
//   let response = try? newJSONDecoder().decode(Response.self, from: jsonData)

import Foundation

// MARK: - ResponseElement
struct ResponseElement: Codable {
    let id, source, language: String
    let version: Int
    let headword: Headword
    let senses: [Sense]
    let relatedEntries: [String]

    enum CodingKeys: String, CodingKey {
        case id, source, language, version, headword, senses
        case relatedEntries = "related_entries"
    }
}

// MARK: - Headword
struct Headword: Codable {
    let text: String
    let pronunciation: Pronunciation
    let pos: String
}

// MARK: - Pronunciation
struct Pronunciation: Codable {
    let value: String
}

// MARK: - Sense
struct Sense: Codable {
    let id: String
    let translations: SenseTranslations
    let examples: [Example]
}

// MARK: - Example
struct Example: Codable {
    let text: String
    let translations: ExampleTranslations
}

// MARK: - ExampleTranslations
struct ExampleTranslations: Codable {
    let br, dk, es, fr: Br
    let ja: Ja
    let no, sv: Br
}

// MARK: - Br
struct Br: Codable {
    let text: String
}

// MARK: - Ja
struct Ja: Codable {
    let text: String
    let alternativeScripts: AlternativeScripts

    enum CodingKeys: String, CodingKey {
        case text
        case alternativeScripts = "alternative_scripts"
    }
}

// MARK: - AlternativeScripts
struct AlternativeScripts: Codable {
    let romaji: String
}

// MARK: - SenseTranslations
struct SenseTranslations: Codable {
    let br, dk, es: Br
    let fr: Fr
    let ja: Ja
    let no, sv: Fr
}

enum Fr: Codable {
    case br(Br)
    case brArray([Br])

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode([Br].self) {
            self = .brArray(x)
            return
        }
        if let x = try? container.decode(Br.self) {
            self = .br(x)
            return
        }
        throw DecodingError.typeMismatch(Fr.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Fr"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .br(let x):
            try container.encode(x)
        case .brArray(let x):
            try container.encode(x)
        }
    }
}

typealias Response = [ResponseElement]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...