Using this code:
import Foundation
let jsonData = """
{
"equipment": [
{
"name": "BigBox",
"origin": "Customer",
"type_codes": [
"XCD",
"QPR"
],
"category": "Shipping",
"product_counts": {
"M": 1,
"D": 2,
"W": 1,
"F": 1
}
},
{
"name": "LittleBox",
"origin": "Manufacturer",
"type_codes": [
"XCD",
"DDP"
],
"category": "Storage",
"product_counts": {
"W": 3,
"F": 2
}
}
]
}
""".data(using: .utf8)!
struct EquipmentListing: Codable {
let equipment: [Equipment]
enum CodingKeys: String, CodingKey {
case equipment
}
}
struct Equipment: Codable {
let name: String
let origin: String
let typeCodes: [String]
let category: String
let productCounts: ProductCounts
enum CodingKeys: String, CodingKey {
case name
case origin
case typeCodes = "type_codes"
case category
case productCounts = "product_counts"
}
}
struct ProductCounts: Codable {
let m: Int?
let d: Int?
let w: Int?
let f: Int?
enum CodingKeys: String, CodingKey {
case m = "M"
case d = "D"
case w = "W"
case f = "F"
}
}
let equipmentListing = try! JSONDecoder().decode(EquipmentListing.self, from: jsonData)
print( equipmentListing.equipment[0].productCounts.d )
This works, but has the drawback that the productCounts
keyed object is turned into a struct with hardcoded members but there could be dozens of possibilities there and I don't want to have to list them all in the code as Optionals. I want to be able to decode my source JSON so that productCounts
comes out as a Dictionary instead of a struct.
Basically, I would like the last line to be this instead:
print( equipmentListing.equipment[0].productCounts["D"] )
** Bonus points if it's possible to change the keys in productCounts
from, eg, D
to Dishwasher
, M
to Microwave
, etc. as the source is decoded so that this possible:
print( equipmentListing.equipment[0].productCounts["Dishwasher"] )
Since you want to map from an arbitrary string to an integer, that's a Dictionary, just as you suggest. You can get rid of the ProductCounts struct and use [String: Int]
.
struct Equipment: Codable {
let name: String
let origin: String
let typeCodes: [String]
let category: String
let productCounts: [String: Int] // <===
enum CodingKeys: String, CodingKey {
case name
case origin
case typeCodes = "type_codes"
case category
case productCounts = "product_counts"
}
}
print( equipmentListing.equipment[0].productCounts["D"] )
// Optional(2)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.