Created
February 27, 2024 17:51
-
-
Save andr3a88/38f4fdf62853ea7ce202158033b0ba47 to your computer and use it in GitHub Desktop.
Using array of mixed Encodable types (in Swift)
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 UIKit | |
/// A type eraser to erase the concrete types of your encodable objects | |
struct AnyEncodable: Encodable { | |
private let encodeClosure: (Encoder) throws -> Void | |
init<T: Encodable>(_ value: T) { | |
encodeClosure = { encoder in | |
try value.encode(to: encoder) | |
} | |
} | |
func encode(to encoder: Encoder) throws { | |
try encodeClosure(encoder) | |
} | |
} | |
// Define a common protocol for all encodable objects | |
protocol Vehicle: Encodable {} | |
// Conform all your encodable objects to this protocol | |
struct PetrolCar: Vehicle { | |
let name: String = "Petrol Car" | |
let manufacturer: String = "Ford" | |
let petrolTankCapacity: Int = 50 | |
} | |
struct ElectricCar: Vehicle { | |
let name: String = "Electric Car" | |
let manufacturer: String = "Tesla" | |
let batteryCapacity: Int = 75 | |
} | |
struct GasCar: Vehicle { | |
let name: String = "Gas Car" | |
let manufacturer: String = "Renault" | |
let gasTankCapacity: Int = 55 | |
} | |
struct F1Car: Vehicle { | |
let name: String = "SF-24" | |
let manufacturer: String = "Ferrari" | |
let petrolTankCapacity: Int = 50 | |
let batteryCapacity: Int = 10 | |
let frontWing: Bool = true | |
let rearWing: Bool = true | |
} | |
// APPROACH TO AVOID | |
struct MixedVehicles: Vehicle { | |
let name: String | |
let manufacturer: String | |
let petrolTankCapacity: Int? | |
let gasTankCapacity: Int? | |
let batteryCapacity: Int? | |
} | |
// Create an array of type-erased encodable objects | |
let vehicles: [AnyEncodable] = [ | |
AnyEncodable(PetrolCar()), | |
AnyEncodable(ElectricCar()), | |
AnyEncodable(GasCar()), | |
AnyEncodable(F1Car()) | |
] | |
do { | |
let jsonData = try JSONEncoder().encode(vehicles) | |
print(String(decoding: jsonData, as: UTF8.self)) | |
} catch { | |
print("Error encoding JSON: \(error)") | |
} | |
// OUTPUT: | |
// [{"petrolTankCapacity":50,"manufacturer":"Ford","name":"Petrol Car"},{"name":"Electric Car","manufacturer":"Tesla","batteryCapacity":75},{"name":"Gas Car","manufacturer":"Renault","gasTankCapacity":55},{"name":"SF-24","manufacturer":"Ferrari","batteryCapacity":10,"petrolTankCapacity":50,"frontWing":true,"rearWing":true}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OUTPUT: