在 Swift 中,为什么 CodingKey 是我看到的与枚举一起使用的协议,用于在结构上使用 Codable 协议?
In Swift, why is CodingKey the protocol I see being used with enums for use of the Codable protocol on a struct?
在 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
}
}
结构 Foo 的每个 属性 都必须是可编码的。其中包括 MyType
。 CodingKey
指定将在 JSON 字典中使用的字符串,不等同于 Codable。 id、name、order 字段已经是 Codable;由标准库提供。
更新
将此扩展添加到 Foo 以更改结构字段标签 encoded/decoded 到 JSON 的方式。我任意将 my_ 添加到您的两个属性中。
extension Foo {
enum CodingKeys: String, CodingKey {
case id
case name
case type = "my_type"
case order = "my_order"
}
}
为什么要使用编码键?
If the keys used in your serialized data format don't match the
property names from your data type, provide alternative keys by
specifying String as the raw-value type for the CodingKeys
enumeration.
示例:-
Json -
let jsonExample = """
{
"id":1,
"name_Of_person":"jack",
"emailId":"Demo@apple.com"
}
""".data(using: .utf8)!
创建符合Codable
协议的struct
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)
}
在 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
}
}
结构 Foo 的每个 属性 都必须是可编码的。其中包括 MyType
。 CodingKey
指定将在 JSON 字典中使用的字符串,不等同于 Codable。 id、name、order 字段已经是 Codable;由标准库提供。
更新 将此扩展添加到 Foo 以更改结构字段标签 encoded/decoded 到 JSON 的方式。我任意将 my_ 添加到您的两个属性中。
extension Foo {
enum CodingKeys: String, CodingKey {
case id
case name
case type = "my_type"
case order = "my_order"
}
}
为什么要使用编码键?
If the keys used in your serialized data format don't match the property names from your data type, provide alternative keys by specifying String as the raw-value type for the CodingKeys enumeration.
示例:-
Json -
let jsonExample = """
{
"id":1,
"name_Of_person":"jack",
"emailId":"Demo@apple.com"
}
""".data(using: .utf8)!
创建符合Codable
协议的struct
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)
}