You have to decode data
depending on type
. That means you have to first decode type
and then continue depending on its value.
Usually to store such items we would use an enum
with associated values:
enum Item: Decodable {
case onboarding(OnboardingData)
case entry(EntryData)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
switch type {
case "onboarding":
let data = try container.decode(OnboardingData.self, forKey: .data)
self = .onboarding(data)
case "entry":
let data = try container.decode(EntryData.self, forKey: .data)
self = .entry(data)
default:
throw DecodingError.unknownType
}
}
private enum CodingKeys: String, CodingKey {
case type
case data
}
private enum DecodingError: String, Error {
case unknownType
}
}
struct OnboardingData: Decodable {
}
struct EntryData: Decodable {
}
OnboardingData
and EntryData
are just type placeholders. You can change them to anything to want, e.g. an array of items. Also, you might wrap arrays inside them.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…