// this uses a dynamic coding key (StockKey) but does not work with nested objects (ideally quote should have many properties inside import SwiftUI import Combine import Foundation /* todo modify to work with json in format: { "AAPL":{"quote":{},"chart":[]}, "MSFT":{"quote":{},"chart":[]} } */ let json = """ { "AAPL" : { "quote" : "asdf asdf asdf", "latestPrice" : 267.99 }, "MSFT" : { "quote" : "asdfasdfas", "latestPrice" : 165.14 } } """ struct StocksModel : Codable { struct StockKey : CodingKey { var stringValue: String init?(stringValue: String) { self.stringValue = stringValue } var intValue: Int? { return nil } init?(intValue: Int) { return nil } static let latestPrice = StockKey(stringValue: "latestPrice")! } let quote : [StockModel] struct StockModel : Codable { let symbol: String let latestPrice: Double } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StockKey.self) var quote: [StockModel] = [] for key in container.allKeys { let nested = try container.nestedContainer(keyedBy: StockKey.self, forKey: key) let latestPrice = try nested.decode(Double.self, forKey: .latestPrice) quote.append(StockModel(symbol: key.stringValue, latestPrice: latestPrice)) } self.quote = quote } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StockKey.self) for item in quote { let key = StockKey(stringValue: item.symbol)! var nested = container.nestedContainer(keyedBy: StockKey.self, forKey: key) try nested.encode(item.latestPrice, forKey: .latestPrice) } } } let decoder = JSONDecoder() if let jsonData = json.data(using: .utf8) { do { let results = try decoder.decode(StocksModel.self, from: jsonData) print(results) } catch { print(error) } }