在Swift中,为什么CodingKey是我看到的用于在结构上使用Codable协议的枚举的协议?
我没有在很多方面对此进行测试,但我一直在尝试复制我发现的所有示例时遇到此错误。我只是在枚举上使用Codable协议就可以获得完美的行为。
// This throws Error
struct Foo: Codable { //! Type 'Foo' does not conform to protocol 'Codable'
var id: String
var name: String
var type: MyType
var order: Int
enum MyType: String, CodingKey {
case this
case that
case and
case theOtherThing
}
}
// This doesn't
struct Foo: Codable {
var id: String
var name: String
var type: MyType
var order: Int
enum MyType: String, Codable {
case this
case that
case and
case theOtherThing
}
}
答案 0 :(得分:3)
struct Foo的每个属性都必须是Codable。这包括MyType
。 CodingKey
指定将在JSON字典中使用哪些字符串,并且不等同于Codable。 id,name,order字段已经是Codable;由标准库提供。
<强>更新强> 将此扩展添加到Foo以更改结构字段标签的编码/解码方式为JSON。我随意将my_添加到你的两个属性中。
extension Foo {
enum CodingKeys: String, CodingKey {
case id
case name
case type = "my_type"
case order = "my_order"
}
}
答案 1 :(得分:2)
为什么要使用编码密钥?
如果序列化数据格式中使用的密钥与 您的数据类型中的属性名称,提供替代键 将String指定为CodingKeys的原始值类型 枚举。
示例: - 强>
Json -
let jsonExample = """
{
"id":1,
"name_Of_person":"jack",
"emailId":"Demo@apple.com"
}
""".data(using: .utf8)!
创建符合struct
协议的Codable
struct UserData: Codable {
var id: Int
var name: String
var email: String
//Set JSON key values for fields in our custom type
private enum CodingKeys: String, CodingKey {
case id //Leave it blank because id matches with json Id
case name = "name_Of_person"
case email = "emailId"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decode(Int.self, forKey: .id)
name = try values.decode(String.self, forKey: .name)
email = try values.decode(String.self, forKey: .email)
}
}
<强>使用 - 强>
//Decode struct using JSONDecoder
let jsonDecoder = JSONDecoder()
do {
let modelResult = try jsonDecoder.decode(UserData.self,from: jsonExample)
print("id is \(modelResult.id) - Name is \(modelResult.name) - email is \((modelResult.email))")
} catch {
print(error)
}