Codable是Swift 4.0 之后苹果增加的,Codable是Encodable和Decodable协议的类型别名。当您Codable用作类型或通用约束时,它匹配符合两种协议的任何类型。
Swift 4.0 之后对于MJExtension/YYModel 等常见的字典转成模型不适用了,苹果提倡使用Codable,用struct 来代替NSObject。
struct 与class的区别: struct是值类型,class是引用类型,值类型在传递和赋值时将进行复制,而引用类型则会使用引用对象指向。class可以继承,类可以被多次引用,struct结构小,使用复制操作,相比一个class的实列被多次引用更加安全。
现在先来创建一个Codable的模型:
struct DQModel:Codable {
var content:String?
var status:Bool?
var num:Int?
}
这里我设置content status num 都是可选类型,这里是为了考虑当服务器返回的数据发生改变了,假如status没有返回,那么不设置可选的话,就会转成模型失败。
Codable类型可以声明一个符合协议的特殊嵌套枚举。当存在该枚举时,其案例用作在编码或解码可编码类型的实例时必须包括的属性的权威列表。枚举案例的名称应与您为类型中的相应属性指定的名称相匹配。
如果在解码实例时它们不存在,或者如果某些属性不应包含在编码表示中,则忽略枚举中的属性。省略的属性需要一个默认值
struct DQModel:Codable {
var content:String?
var status:Bool?
var num:Int?
var time:String = ""
enum CodingKeys :String,CodingKey {
case content
case status
case num = "number"
}
}
time 是可忽视的,当JSON的键与数据类型中的属性名称不匹配时,就通过指定枚举String的原始值类型来提供备用键 case num = "number"。
现在把JSON转成Model:
if let JSONData = try? JSONSerialization.data(withJSONObject: JSON, options: []) {
let decoder = JSONDecoder()
do {
let model = try decoder.decode(DQModel, from: JSONData)
return model
} catch let error as NSError {
print(error.localizedDescription)
}
}
[String: Any]转成Model:
let encoder = JSONEncoder()
do {
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(model)
if let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) {
if let dict = jsonDict as? [String: Any] {
return dict
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
当模型有嵌套:
struct DQModel:Codable {
var content:String?
var status:Bool?
var num:Int?
var time:String = ""
var bank:DQBankCardModel?
enum CodingKeys :String,CodingKey {
case content
case status
case num = "number"
case bank
}
}
struct DQBankCardModel:Codable {
var name:String = ""
var number:String = ""
}
未完待续...
网友评论