swift 字典->模型-相互轉(zhuǎn)換

***支持swift5.0***

1.swift4出現(xiàn)了Codable協(xié)議,只要繼承該協(xié)議,便可使用系統(tǒng)的模型轉(zhuǎn)換,字典轉(zhuǎn)模型,模型轉(zhuǎn)字典。

其實(shí)CodableDecodable協(xié)議和Encodable協(xié)議的歸結(jié)

Codable是這樣定義的:

系統(tǒng)Codable的定義

2.Decodable是用來解檔,用我的話來說,就是用來Data轉(zhuǎn)換成模型。

我寫了兩種 模型轉(zhuǎn)換的方式:

2.1?一種是定義一個(gè)?LsqDecoder 類型,用于 字典、數(shù)組轉(zhuǎn)換成模型:

struct LsqDecoder {

? ? //TODO:轉(zhuǎn)換模型(單個(gè))

? ?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

? ? }

//多個(gè)

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用于解析數(shù)據(jù),所以添加了該方法,如果沒有使用SwiftyJSON,請注釋或者刪掉以下方法

? ? /*

?? ? 如果是單個(gè),則 Model.decode(json)

?? ? 如果是多個(gè),則 [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.好了,看看怎么用吧。

例如我有一個(gè)這樣的數(shù)據(jù)需要解析:

數(shù)據(jù)

先寫一個(gè)模型,用來接收數(shù)據(jù)

模型

使用:

單個(gè)型

如果這里,我只想解析 books,又咋整呢?,相當(dāng)于就是數(shù)組轉(zhuǎn)多個(gè)模型啦,沒啥區(qū)別。

數(shù)組型

好了,數(shù)據(jù)轉(zhuǎn)模型說完了。

3.下面說說模型歸檔,有時(shí)候需要將模型轉(zhuǎn)換成json、字典、或者數(shù)組,又該如何呢?這里我也準(zhǔn)備了兩種方案。

3.1一種是定義一個(gè)?LsqEncoder 類型,用于模型轉(zhuǎn)換成字典、json字符串(集合的沒寫):

//模型轉(zhuǎn)字典,或轉(zhuǎn)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

? ? }

}

附上圖片:

模型轉(zhuǎn)字典,或轉(zhuǎn)json字符串

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]

? ? }

}

附上圖片:

模型歸檔

還是如何使用的問題:我們還是用剛才的數(shù)據(jù)和模型來做示例,但是模型僅僅只實(shí)現(xiàn)了Decodable協(xié)議,所以,這里要改成


或者:

個(gè)人喜好用第二種:


好的,說完了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容