要使一个类型符合Decodable
和Encodable
协议,它必须能够将其属性值编码为JSON数据或将JSON数据解码为属性值。然而,并非所有类型的属性都可以直接编码或解码为JSON数据。
以下是一些常见的不符合Decodable
和Encodable
协议的情况以及解决方法:
Decodable
和Encodable
协议要求属性类型必须是标准的JSON类型,例如字符串、数字、布尔值、数组和字典。如果属性类型是自定义类型或非标准的类型,你需要手动实现Decodable
和Encodable
协议中的方法来转换属性值。struct Person: Decodable, Encodable {
var name: PersonName // 自定义类型
var age: Int // 符合标准类型
enum CodingKeys: String, CodingKey {
case name
case age
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(PersonName.self, forKey: .name)
age = try container.decode(Int.self, forKey: .age)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(age, forKey: .age)
}
}
struct PersonName: Decodable, Encodable {
var first: String
var last: String
}
CodingKeys
枚举来映射属性与JSON键之间的关系。如果你希望忽略某些属性,可以在encode(to:)
和init(from:)
方法中直接忽略它们。struct Person: Decodable, Encodable {
var name: String
var age: Int
enum CodingKeys: String, CodingKey {
case name = "full_name"
case age
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
age = try container.decode(Int.self, forKey: .age)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(age, forKey: .age)
}
}
Decodable
和Encodable
协议来提供自定义的编码和解码逻辑。struct Person: Decodable, Encodable {
var name: String
var birthDate: Date // 日期类型
enum CodingKeys: String, CodingKey {
case name
case birthDate = "birth_date"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
let dateString = try container.decode(String.self, forKey: .birthDate)
// 自定义解码日期逻辑
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
birthDate = dateFormatter.date(from: dateString) ?? Date()
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
// 自定义编码日期逻辑
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: birthDate)
try container.encode(dateString, forKey: .birthDate)
}
}
通过上述方法,你可以解决不符合Decodable
和Encodable
协
上一篇:不符合64位要求(2022)
下一篇:不符合HDFS模式的文件怎么办?