Карта JSON как массив или объект - PullRequest
1 голос

У меня есть json, который показывает мне иногда массив, иногда простой объект

"ownersPeriod" : [
        {
          "dateTo" : "2013-06-17",
          "dateFrom" : "2012-09-15"
        },
        {
          "dateTo" : "2016-06-30",
          "dateFrom" : "2013-06-17"
        },
        {
          "dateTo" : "",
          "dateFrom" : "2016-06-30"
        }
      ],

"ownersPeriod" : {
        "dateTo" : "",
        "dateFrom" : "2008-03-29"
      },

, как отобразить или преобразовать простой объект в массив этого типа

Я сопоставляю массив, используя маппер объекта

public var ownersPeriodArray: [Model] = []

Здесь я использую библиотеку ObjectMapper для преобразования json в мою модель let model = Mapper (). Map (JSON: json)

1 Ответ

5 голосов
/ 29 марта 2020

Вы можете попробовать запустить код здесь, если хотите быстро его проверить: http://online.swiftplayground.run/

import Foundation

let jsonObject = """
{
    "ownersPeriod" : [
        {
          "dateTo" : "2013-06-17",
          "dateFrom" : "2012-09-15"
        },
        {
          "dateTo" : "2016-06-30",
          "dateFrom" : "2013-06-17"
        },
        {
          "dateTo" : "",
          "dateFrom" : "2016-06-30"
        }
      ]
}
""".data(using: .utf8)!

let jsonArray = """
{
    "ownersPeriod" : {
        "dateTo" : "",
        "dateFrom" : "2008-03-29"
      }
}
""".data(using: .utf8)!

struct Owner: Codable {
    let ownersPeriod: CombinedType
}

struct OwnerPeriod: Codable {
    var dateTo: String
    var dateFrom: String
}

enum CombinedType: Codable {
    case array([OwnerPeriod])
    case object(OwnerPeriod)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = try .array(container.decode(Array.self))
        } catch DecodingError.typeMismatch {
            do {
                self = try .object(container.decode(OwnerPeriod.self))
            } catch DecodingError.typeMismatch {
                throw DecodingError.typeMismatch(CombinedType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded type not expected"))
            }
        }
    }

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

let decoder = JSONDecoder()
let object = try decoder.decode(Owner.self, from: jsonObject)
let array = try decoder.decode(Owner.self, from: jsonArray)

print(object)
print(array)

Он печатает:

Owner(ownersPeriod: SwiftPlayground.CombinedType.array([SwiftPlayground.OwnerPeriod(dateTo: "2013-06-17", dateFrom: "2012-09-15"), SwiftPlayground.OwnerPeriod(dateTo: "2016-06-30", dateFrom: "2013-06-17"), SwiftPlayground.OwnerPeriod(dateTo: "", dateFrom: "2016-06-30")]))

Owner(ownersPeriod: SwiftPlayground.CombinedType.object(SwiftPlayground.OwnerPeriod(dateTo: "", dateFrom: "2008-03-29")))
...