Created
February 3, 2020 20:31
-
-
Save emrepun/0f2d76ffdedce26fc2dec95dfe037347 to your computer and use it in GitHub Desktop.
Parse json item array (consists of different items) with enums & associated values
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 | |
struct GeometricShapes: Decodable { | |
let items: [Object] | |
} | |
enum Object: Decodable { | |
case square(Square) | |
case sphere(Sphere) | |
case cylinder(Cylinder) | |
case unknown | |
enum CodingKeys: String, CodingKey { | |
case type | |
} | |
init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
guard let type = try? container.decode(ObjectType.self, forKey: .type) else { | |
self = .unknown | |
return | |
} | |
let objectContainer = try decoder.singleValueContainer() | |
switch type { | |
case .square: | |
let square = try objectContainer.decode(Square.self) | |
self = .square(square) | |
case .sphere: | |
let sphere = try objectContainer.decode(Sphere.self) | |
self = .sphere(sphere) | |
case .cylinder: | |
let cylinder = try objectContainer.decode(Cylinder.self) | |
self = .cylinder(cylinder) | |
case .unknown: | |
self = .unknown | |
} | |
} | |
} | |
enum ObjectType: String, Decodable { | |
case square | |
case sphere | |
case cylinder | |
case unknown | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let type = try container.decode(String.self) | |
self = ObjectType(rawValue: type) ?? .unknown | |
} | |
} | |
struct Square: Decodable { | |
let sideLength: Int | |
enum CodingKeys: String, CodingKey { | |
case sideLength = "side_length" | |
} | |
} | |
struct Sphere: Decodable { | |
let diameter: Int | |
} | |
struct Cylinder: Decodable { | |
let diameter: Int | |
let height: Int | |
} | |
let JSON = """ | |
{ | |
"items": [ | |
{ | |
"type": "square", | |
"side_length": 12 | |
}, | |
{ | |
"type": "sphere", | |
"diameter": 4 | |
}, | |
{ | |
"type": "cylinder", | |
"diameter": 4, | |
"height": 10 | |
}, | |
{ | |
"type": "lalala", | |
"unknown_key": 0 | |
} | |
] | |
} | |
""".data(using: .utf8)! | |
let decoder = JSONDecoder() | |
let geometricObjects = try decoder.decode(GeometricShapes.self, from: JSON) | |
let items = geometricObjects.items | |
// Here we just parse and print some values of the models. | |
// This is how you can parse with a wrapper enum with associated value. | |
items.forEach({ | |
switch $0 { | |
case .cylinder(let cylinder): | |
print("Diameter of cylinder is: \(cylinder.diameter)") | |
print("Height of cylinder is: \(cylinder.height)") | |
case .sphere(let sphere): | |
print("Diameter of sphere is: \(sphere.diameter)") | |
case .square(let square): | |
print("Side length of square is: \(square.sideLength)") | |
case .unknown: | |
print("We have an unknown type.") | |
} | |
}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment