Я работаю над кодированием и декодированием JSON, но некоторые проблемы очень раздражают, и я не знаю, как использовать CodingKeys
в наследуемых классах.
У меня есть два класса ResponseBean
и ResponseWithObjectBean<T>
.
Вот определение класса ответа:
public class ResponseBean: Codable
{
//This is only sample, I define `CodingKeys` because the property in json is in different name.
private enum CodingKeys: String, CodingKey
{
case intA
case intB
}
public var intA: Int32 = 0
public var intB: Int32 = 0
}
public class ResponseWithObjectBean<T: Codable> : ResponseBean
{
/*
Here I don't know how to define an enum to confirm protocl CondingKey.
I defined an enum named CodingKeys or whatever, they just don't work and
the testMessage and obj are still nil.
But if I implement the init(from decoder: Decoder) construction and manually
pass the coding keys which I defined to the decode function, all works fine.
*/
public var testMessage: String? = nil
public var obj: T? = nil
}
и я получу пользователя из ответа:
public class User: Codable
{
private enum CodingKeys: String, CodingKey
{
case name
case age
}
public var name: String? = nil
public var age: Int32? = nil
}
Вот тест JSON:
var testJson = """
{
"intA": 10,
"intB": 20,
"testMessage": "This is a test json",
"obj":{
"name": "LiHong",
"age": 11
}
}
"""
Вот как я бегу:
do{
var responseData = testJson.data(using: .utf8)
var decoder = JSONDecoder()
var response: ResponseWithObjectBean<User> = try decoder.decode(ResponseWithObjectBean<User>.self, from: responseData)
}catch let e{
}
Я не знаю, как определить CodingKeys
в ResponseWithObjectBean
классе, и даже я знал, что это не работает вообще. Но если я реализую init(from decoder: Decoder) throws
конструкцию и вручную передам ключи кодирования, которые я определил в ResponseWithObjectBean
, я смогу получить все свойства.