Last active
April 8, 2021 00:05
-
-
Save absoftware/880561fb8ed343304598de2c2de24a29 to your computer and use it in GitHub Desktop.
Hot to make Swift's [String: Any] decodable?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
let json = """ | |
{ | |
"keyNumber1": { | |
"type": "payload", | |
"data": { | |
"id": "someId1", | |
"eventName": "Event Name 1", | |
"metadata": [] | |
} | |
}, | |
"keyNumber2": { | |
"type": "metadata", | |
"data": { | |
"name": "Metadata Name", | |
"price": 123.4, | |
"rating": 100 | |
} | |
} | |
} | |
""" | |
enum DataType: String, Codable { | |
case payload | |
case metadata | |
} | |
struct Payload: Codable { | |
let id: String | |
let eventName: String | |
let metadata: [Metadata] | |
} | |
struct Metadata: Codable { | |
let name: String? | |
let price: Double? | |
let rating: Int? | |
} | |
enum MyValue: Decodable { | |
case payload(_ payload: Payload) | |
case metadata(_ metadata: Metadata) | |
private enum CodingKeys: String, CodingKey { | |
case `type` | |
case `data` | |
} | |
init(from decoder: Decoder) throws { | |
let map = try decoder.container(keyedBy: CodingKeys.self) | |
let dataType = try map.decode(DataType.self, forKey: .type) | |
switch dataType { | |
case .payload: | |
self = .payload(try map.decode(Payload.self, forKey: .data)) | |
case .metadata: | |
self = .metadata(try map.decode(Metadata.self, forKey: .data)) | |
} | |
} | |
} | |
let decodedData = try JSONDecoder().decode([String: MyValue].self, from: json.data(using: .utf8)!) | |
print(decodedData) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment