wongzigii
(Zigii Wong)
1
How to decode JSON with dynamic key base on generic T?
I got an error: Raw value for enum case must be a literal.
struct GraphQLActionResp<T: GraphQLAction>: GraphQLDecodable {
var root: RespData?
enum CodingKeys: String, CodingKey {
case root = T.rootKey // Raw value for enum case must be a literal
}
struct RespData: Decodable {
var isOk: Bool
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.root = try container.decode(RespData.self, forKey: CodingKeys.root)
}
}
protocol GraphQLAction: Decodable {
static var rootKey: String { get }
}
struct AAction: GraphQLAction {
static var rootKey: String {
return "A"
}
}
struct BAction: GraphQLAction {
static var rootKey: String {
return "B"
}
}
It's pretty simple: Don't use an enum for your coding keys. Just use a struct that conforms to the CodingKey protocol:
struct GraphQLActionResp<T: GraphQLAction>: Codable {
var root: RespData?
struct CodingKeys: CodingKey {
init?(intValue: Int) {
return nil
}
init(stringValue: String) {
self.stringValue = stringValue
}
let stringValue: String
let intValue: Int? = nil
static var root: Self { Self(stringValue: T.rootKey) }
}
struct RespData: Codable {
var isOk: Bool
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.root = try container.decode(RespData.self, forKey: CodingKeys.root)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.root, forKey: .root)
}
}
protocol GraphQLAction: Decodable {
static var rootKey: String { get }
}
struct AAction: GraphQLAction {
static var rootKey: String {
return "A"
}
}
struct BAction: GraphQLAction {
static var rootKey: String {
return "B"
}
}
1 Like