最近使用swift开发,用原生的Decodable将json转换为模型,遇到了一些问题,在这里做个记录 。
1.某个字段类型可变
某个字段有时候为Int,有时候为String
当dataType=1时为valueString类型,当dataType = 2时value为Int类型
处理办法: 将 value 声明为String?类型重写 init(from decoder: Decoder)方法 示例代码如下
struct SmartControlModelTemplateAttributeValueModel {
var dataType: Int
var displayName: String
var value: String?
init(dataType: Int, displayName: String, value: String?) {
self.dataType = dataType
self.displayName = displayName
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
dataType = try container.decode(Int.self, forKey: .dataType)
displayName = try container.decode(String.self, forKey: .displayName)
do {
value = try String(container.decode(Int.self, forKey: .value))
} catch DecodingError.typeMismatch {
value = try container.decode(String.self, forKey: .value)
}
}
}
2. 模型嵌套
服务器返回json中有多个数组字典类型嵌套,字典键值类型不单一 如json:
解决方案: 将每一个模型映射 示例代码 :
struct SmartControlModelTemplateModel {
var deviceCategory: String
var version: String
var id: Int
var deviceType: Int
var deviceNodeType: Int
var attributes: [SmartControlModelTemplateAttributesModel]
// var events: [SmartControlModelTemplateEventsModel]
}
extension SmartControlModelTemplateModel: Decodable{
enum CodingKeys: String, CodingKey {
case deviceCategory
case version
case id
case deviceType
case deviceNodeType
case attributes
// case events
}
}
struct SmartControlModelTemplateAttributesModel {
var code: String
var displayName: String
var description: String
var readWriteMode: Int
var custom: Int
var direction: Int
var dataType: Int
var value:[SmartControlModelTemplateAttributeValueModel]?
var setup:SmartControlModelTemplateAttributeSetupModel?
}
extension SmartControlModelTemplateAttributesModel: Decodable{
enum CodingKeys: String, CodingKey {
case code
case displayName
case description
case readWriteMode
case custom
case direction
case dataType
case value
case setup
}
}
struct SmartControlModelTemplateAttributeValueModel {
var dataType: Int
var displayName: String
var value: String?
init(dataType: Int, displayName: String, value: String?) {
self.dataType = dataType
self.displayName = displayName
self.value = value
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
dataType = try container.decode(Int.self, forKey: .dataType)
displayName = try container.decode(String.self, forKey: .displayName)
do {
value = try String(container.decode(Int.self, forKey: .value))
} catch DecodingError.typeMismatch {
value = try container.decode(String.self, forKey: .value)
}
}
}
extension SmartControlModelTemplateAttributeValueModel: Decodable{
enum CodingKeys: String, CodingKey {
case dataType
case displayName
case value
}
}
struct SmartControlModelTemplateAttributeSetupModel {
var max: String
var min: String
var step: String
var unit: String
var unitName: String
}
extension SmartControlModelTemplateAttributeSetupModel: Decodable{
enum CodingKeys: String, CodingKey {
case max
case min
case step
case unit
case unitName
}
}
没怎么写过文档,看的老铁请轻喷
网友评论