Кодируемые: выравнивающие структуры - PullRequest
0 голосов
/ 21 марта 2019

Допустим, у меня есть некоторый тип, который имеет представление JSON как таковое:

{
  "count": 3,
  "name": "Pianos",
  "type": "instrument",
  "id": 1,
}

Допустим, я хочу представить это как объект Swift, который выглядит следующим образом:

struct SomeObject: Codable { // this is the object I'd like to represent
  let id: Int
  let details: SomeDetails
}

struct SomeDetails: Codable {
  let count: Int
  let name: String
  let type: String
}

Расшифровка этого объекта - легкая задача. Но как будет работать кодирование в этом случае, чтобы я мог кодировать в плоскую структуру - ту же структуру, которую я использовал для создания этого объекта и использовал в примере JSON выше?

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Но как будет работать кодирование в этом случае?

Это просто работает:

struct SomeObject: Codable { 
    let id: Int
    let details: SomeDetails
}
struct SomeDetails: Codable {
    let count: Int
    let name: String
    let type: String
}
let someobject = SomeObject(id: 10, details: SomeDetails(count: 3, name: "ho", type: "hey"))
let json = try! JSONEncoder().encode(someobject)

Если вы настаиваете на искусственном выравнивании, просто напишите свой собственный encode(to:), вот так:

struct SomeObject: Codable {
    let id: Int
    let details: SomeDetails
    enum Keys : String, CodingKey {
        case id
        case count
        case name
        case type
    }
    func encode(to enc: Encoder) throws {
        var con = try enc.container(keyedBy: Keys.self)
        try con.encode(id, forKey: .id)
        try con.encode(details.count, forKey: .count)
        try con.encode(details.name, forKey: .name)
        try con.encode(details.type, forKey: .type)
    }
}
struct SomeDetails: Codable {
    let count: Int
    let name: String
    let type: String
}
let someobject = SomeObject(id: 10, details: SomeDetails(count: 3, name: "ho", type: "hey"))
let json = try! JSONEncoder().encode(someobject)
0 голосов
/ 21 марта 2019

Если кто-нибудь прочтет это в будущем (привет!), Это просто вопрос перехода к вашему созданному типу, который упаковывает значения вашего абстрагирования.

struct SomeDetails: Codable {
    let count: Int
    let name: String
    let type: String
}


struct SomeObject: Codable {
    let id: Int
    let details: SomeDetails

    enum CodingKeys: String, CodingKey {
        case id
    }

    enum DetailKeys: String, CodingKey {
        case count, name, type
    }

    init(from decoder: Decoder) throws {
        let topLevelContainer = try decoder.container(keyedBy: CodingKeys.self)
        let detailContainer = try decoder.container(keyedBy: DetailKeys.self)

        id = try topLevelContainer.decode(Int.self, forKey: .id)
        details = SomeDetails(
            count: try detailContainer.decode(Int.self, forKey: .count),
            name: try detailContainer.decode(String.self, forKey: .name),
            type: try detailContainer.decode(String.self, forKey: .type))
    }

    func encode(to encoder: Encoder) throws {
        var topLevelContainer = encoder.container(keyedBy: CodingKeys.self)
        try topLevelContainer.encode(id, forKey: .id)

        var detailContainer = encoder.container(keyedBy: DetailKeys.self)
        try detailContainer.encode(details.count, forKey: .count)
        try detailContainer.encode(details.name, forKey: .name)
        try detailContainer.encode(details.type, forKey: .type)
    }
}
...