在Swift中,需要将Json数据转为实体时,一种简单的方式就是使用系统提供的JSONDecoder进行解码,这种方式需要实体类或结构体继承(实现)(java说法)一个类型别名(typealias)为Codable的东西。这个东西长这样:
/// A type that can convert itself into and out of an external representation.
///
/// `Codable` is a type alias for the `Encodable` and `Decodable` protocols.
/// When you use `Codable` as a type or a generic constraint, it matches
/// any type that conforms to both protocols.
public typealias Codable = Decodable & Encodable
普通的类或结构体,直接继承Codable 就行了,可以不用做别的实现,要是属性中有引用别的类或结构体,需要这个属性也要继承Codable ,如下:
struct NewsResponse :Codable {
var code: Int
var msg: String
var result: ResultModel
struct ResultModel : Codable {
var curpage: Int
var allnum: Int
var newslist: [ListModel]
struct ListModel : Codable {
var id: String
var ctime: String
var title: String
let description: String
var source: String
var picUrl: String
var url: String
}
}
}
但是如果这个类或结构体的属性中有泛型的话,需要多做一些处理,不然会有编译时错误,如图:
需要多做一下处理:
也可以多做一些处理:
init(code: Int?, data: T?, msg: String?) {
self.code = code
self.data = data
self.msg = msg
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
code = try container.decode(Int.self, forKey: .code)
data = try container.decode(T.self, forKey: .data)
msg = try container.decode(String.self, forKey: .msg)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(code, forKey: .code)
try container.encode(data, forKey: .data)
try container.encode(msg, forKey: .msg)
}
private enum CodingKeys: String, CodingKey {
case code
case data
case msg
}
然后就可以解析数据了:
do {
let base = try JSONDecoder().decode(BaseBN<UserBN>.self, from: jsonData)
let user=base.data
if user != nil {
self.login(user: user!)
}
print(user as Any)
} catch {
print("Error decoding JSON: \(error)")
}