Codable是swift4.0中的一个特性,它是由Encodable和Decodable两个协议组成的:
public typealias Codable = Decodable & Encodable
Encodable这个协议用在那些需要被编码的数据类型上。如果遵循了这个协议,并且这个类的所有属性都是Encodable的话,编辑器就会自动对该数据类型进行编码操作。
Decodable这个协议用在那些需要被解码的数据类型上。如果遵循了这个协议,那么编辑器则会自动对该数据类型进行解码操作
下来我们用一个例子来展示一下Codable的使用:
let json = """
{
"name": "codable",
"age": 22,
"desc": "data analysis framework in swift"
}
"""
/// 建立模型
struct Coda : Codable {
var name: String?
var age: Int?
var desc: String?
}
/// JSON 转换为Model
let decoder = JSONDecoder()
// 数组模型转化 (注意:先将json字符串转为data)
let products = try decoder.decode(Coda.self, from: json.data(using:.utf8)!)
如果后台返回的Json数据结构比较复杂的话,比如我们可以在struct中再嵌套一个struct来建立模型,同时新建立的模型也必须遵循Codable协议。
但是有时候后台的命名与我们前端创建的不一致,这个时候我们就需要采用映射机制来解决这个问题了。这里列出两种解决方案: 方案一:采用CodingKey协议,进行枚举映射
/// 只需修改模型,实现CodingKey协议
struct Coda : Codable {
var name: String
var age: Int
var desc: String
/// 自定义字段属性
/// 注意 1.需要遵守Codingkey 2.每个字段都要枚举
private enum CodingKeys: String, CodingKey {
case name = "_name"
case age
case desc
}
}
方案二:通过Decoder的keyDecodingStrategy属性,将属性的值设置为convertFromSnakeCase,这样我们就不需要额外的代码处理了
/// 只需增加一行代码
let decoder = JSONDecoder()
// 编码策略 使用从蛇形转化为大写 encode时同样也可将驼峰命名法转化为下划线
decoder.keyDecodingStrategy = .convertFromSnakeCase
let products = try decoder.decode(Coda.self, from: json.data(using:.utf8)!)
keyDecodingStrategy是一个枚举值,他还提供了自定义转化规则
public enum KeyDecodingStrategy {
case useDefaultKeys
case convertFromSnakeCase
case custom(([CodingKey]) -> CodingKey) //自定义转化规则
}
let json = """
{
"_name": "Codable",
"age": 200,
"desc": "data analysis framework in swift"
}
"""
let decoder = JSONDecoder()
// 自定义转化规则
decoder.keyDecodingStrategy = .custom({ (keys) -> CodingKey in
let lastKey = keys.last!
guard lastKey.intValue == nil else { return lastKey }
// 将首字母大写的转化为小写的
let stringValue = lastKey.stringValue.prefix(1).lowercased() +lastKey.stringValue.dropFirst()
return AnyKey(stringValue: stringValue)!
})