Skip to content

Instantly share code, notes, and snippets.

@absoftware
Last active April 8, 2021 00:05
Show Gist options
  • Save absoftware/880561fb8ed343304598de2c2de24a29 to your computer and use it in GitHub Desktop.
Save absoftware/880561fb8ed343304598de2c2de24a29 to your computer and use it in GitHub Desktop.
Hot to make Swift's [String: Any] decodable?
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