***支持swift5.0***
1.swift4出现了Codable协议,只要继承该协议,便可使用系统的模型转换,字典转模型,模型转字典。
其实Codable是Decodable协议和Encodable协议的归结
Codable是这样定义的:
2.Decodable是用来解档,用我的话来说,就是用来Data转换成模型。
我写了两种 模型转换的方式:
2.1 一种是定义一个 LsqDecoder 类型,用于 字典、数组转换成模型:
struct LsqDecoder {
//TODO:转换模型(单个)
public static func decode<T>(_type:T.Type, param: [String:Any]) ->T? where T: Decodable {
guard let jsonData =self.getJsonData(with: param) else {
return nil
}
guard let model = try?JSONDecoder().decode(type, from: jsonData) else {
return nil
}
return model
}
//多个
public static func decode<T>(_type:T.Type, array: [[String:Any]]) -> [T]? where T: Decodable {
guard let data =self.getJsonData(with: array) else {
return nil
}
guard let models =try? JSONDecoder().decode([T].self, from: data) else {
return nil
}
return models
}
public static func getJsonData(with param:Any) ->Data? {
if !JSONSerialization.isValidJSONObject(param) {
return nil
}
guard let data =try? JSONSerialization.data(withJSONObject: param, options: []) else {
return nil
}
return data
}
}
附上截图:
2.2.一种是延展 Decodable
extension Decodable {
///dictionary->模型 temp: Model.decode(dic)
public static func decode(_dictionary: [String:Any]) ->Self? {
guard let data = self.getJsonData(with: dictionary) else {
return nil
}
guard let model =try?JSONDecoder().decode(Self.self, from: data) else {
return nil
}
return model
}
///array->模型 temp:[Model].decode(array)
public static func decode(_array: [[String:Any]]) ->Self? {
guard let data =self.getJsonData(with: array) else {
return nil
}
guard let model =try?JSONDecoder().decode(Self.self, from: data) else {
return nil
}
return model
}
///JSON->模型
///此处,本人用了SwiftyJSON用于解析数据,所以添加了该方法,如果没有使用SwiftyJSON,请注释或者删掉以下方法
/*
如果是单个,则 Model.decode(json)
如果是多个,则 [Model].decode(json)
*/
public static func decode(_json:JSON) ->Self? {
guard let data =try? json.rawData() else {
retur nnil
}
guard let model =try?JSONDecoder().decode(Self.self, from: data) else {
return nil
}
return model
}
public static func getJsonData(with param:Any) -> Data? {
if !JSONSerialization.isValidJSONObject(param) {
return nil
}
guard let data =try?JSONSerialization.data(withJSONObject: param, options: []) else {
return nil
}
return data
}
}
附上截图:
3.好了,看看怎么用吧。
例如我有一个这样的数据需要解析:
先写一个模型,用来接收数据
使用:
如果这里,我只想解析 books,又咋整呢?,相当于就是数组转多个模型啦,没啥区别。
好了,数据转模型说完了。
3.下面说说模型归档,有时候需要将模型转换成json、字典、或者数组,又该如何呢?这里我也准备了两种方案。
3.1一种是定义一个 LsqEncoder 类型,用于模型转换成字典、json字符串(集合的没写):
//模型转字典,或转json字符串
struct LsqEncoder {
public static func encoder(toString model:T) ->String? where T: Encodable {
let encoder =JSONEncoder()
encoder.outputFormatting = .prettyPrinted
guard let data =try? encoder.encode(model) else {
return nil
}
guard let jsonStr =String(data: data, encoding: .utf8) else {
return nil
}
return jsonStr
}
public static func encoder(toDictionary model:T) -> [String:Any]? where T: Encodable {
let encoder =JSONEncoder()
encoder.outputFormatting = .prettyPrinted
guard let data =try? encoder.encode(model) else {
return nil
}
guard let dict =try?JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String:Any] else{
return nil
}
return dict
}
}
附上图片:
3.2 第二种方案,还是延展。
//TODO:模型归档
extension Encodable {
public func encoder() ->Data? {
let ecd =JSONEncoder()
ecd.outputFormatting = .prettyPrinted
return try? ecd.encode(self)
}
}
extension Data {
///Data->Dictionary
public func toDictionary() -> [String:Any]? {
return try? JSONSerialization.jsonObject(with: self, options: .mutableLeaves) as? [String:Any]
}
///Data->String
public func toString() ->String? {
return String(data:self, encoding: .utf8)
}
///Data->JSON
///本人使用了SwiftyJSON,如未使用SwiftyJSON,请注释或删除以下方法
public func toJSON() ->JSON? {
return JSON(data:self)
}
///Data->Array
public func toArrray() -> [Any]? {
return try? JSONSerialization.jsonObject(with: self, options: .mutableLeaves) as? [Any]
}
}
附上图片:
还是如何使用的问题:我们还是用刚才的数据和模型来做示例,但是模型仅仅只实现了Decodable协议,所以,这里要改成
或者:
个人喜好用第二种:
好的,说完了。