Мне нужно декодировать заданную структуру JSON, поступающую из API в Swift 4. Проблема в том, что в какой-то момент дерева у меня есть на одном уровне разные типы данных, и один из типов может иметь подэлементы.
Я пробовал несколько методов JSONDecoder и Decodable, но пока не нашел решения.
Упрощенный JSON:
{
"menuName": "Menu 1",
"menuId": 1,
"menuGroups": [
{
"type": "group",
"name": "Group 1",
"menuEntry": [
{
"type": "group",
"name": "Sub Group 1.1",
"menuEntry": [
{
"type": "menuItem",
"productName": "Item 1",
"productPrice": "9.00"
},
{
"type": "menuItem",
"productName": "Item 2",
"productPrice": "12.00"
}
]
}, {
"type": "menuItem",
"productName": "Item 3",
"productPrice": "9.00"
}
]
}
]
}
Вот декодируемые данные, которые я пытаюсь использовать:
struct Menu: Decodable {
let menuName: String
let menuId: Int
let categories: [MenuCategory]
enum CodingKeys : String, CodingKey {
case menuName
case menuId
case categories = "menuGroups"
}
}
struct MenuCategory: Decodable {
let type: String
let name: String
let items: [CategoryItem]
enum CodingKeys : String, CodingKey {
case type
case name
case items = "menuEntry"
}
}
enum CategoryItem: Decodable {
case group(MenuCategory)
case menuItem(MenuItem)
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
let item = try container.decode(MenuCategory.self)
self = .group(item)
return
} catch let err {
print("error decoding category: \(err)")
}
do {
let item = try container.decode(MenuItem.self)
self = .menuItem(item)
return
} catch let err {
print("error decoding item: \(err)")
}
try self.init(from: decoder)
}
}
struct MenuItem: Decodable {
let type: String
let productName: String
let productPrice: String
enum CodingKeys : String, CodingKey {
case type = "type"
case productName
case productPrice
}
}
Я думаю, что с помощью:
let container = try decoder.singleValueContainer()
неправильно, потому что контейнер не должен быть контейнером с одним значением, но я не знаю, что выбрать/сделать отсюда...
У кого-нибудь есть идеи по этому поводу? Как бы вы раскодировали JSON, как в примере?