#ios #json #swift #codable #decodable
#iOS #json #swift #codable #декодируемый
Вопрос:
У меня есть следующий пример JSON
let json = """
{
"str": [
{
"abv": "4.4",
"weight": "4.1",
"volume": "5.0"
}
]
}
""".data(using: .utf8)!
И следующие Decoable
структуры
struct Outer: Decodable {
let stri: [Garten]
enum CodingKeys: String, CodingKey {
case stri = "str"
}
struct Garten: Decodable {
let alcoholByVol: String
let weight: String
let vol: String
enum CodingKeys: String, CodingKey {
case alcoholByVol = "abv"
case weight = "weight"
case vol = "volume"
}
}
}
Я хочу знать, есть ли какой-либо способ избежать внешнего struct
. В основном он присутствует только для этого одного ключа для декодирования внутреннего массива.
Вот как я сейчас декодирую это
let attrs = try! decoder.decode(Outer.self, from: json)
Но мне любопытно, есть ли что-то похожее на
let attrs = try! decoder.decode([[String: [Outer]].self, from: json)
Комментарии:
1. Да, вы можете, но есть один [ to much
2. Вам также необходимо заменить
Outer
наOuter.Garten
like:let attrs = try! decoder.decode([String: [Outer.Garten]].self, from: json)
Ответ №1:
Вы можете Outer
полностью удалить и декодировать a [String: [Garten]].self
. Затем получите значение, связанное с "str"
ключом:
let attrsDict = try! decoder.decode([String: [Garten]].self, from: json)
let attrs = attrsDict["str"]!
Вы можете обернуть это в функцию:
func decodeNestedObject<T: Codable>(_ type: T.Type, key: String,
from data: Data, using decoder: JSONDecoder = JSONDecoder()) throws -> T {
try decoder.decode([String: T].self, from: data)[key]!
}
Использование:
let attrs = try decodeNestedObject([Garten].self, key: "str", from: data)
Комментарии:
1. Спасибо! Я уверен, что я пробовал это предложение раньше, но по какой-то причине оно работает сейчас. Большое спасибо за помощь.