Swift4: Codable->字典轉(zhuǎn)模型的具體實(shí)現(xiàn)

一、字典轉(zhuǎn)模型

  • 現(xiàn)有如下JSON數(shù)據(jù)
let dict: [String : Any] = [
    "name" : "zhangsan",
    "height" : 1.88,
    "pet" : [
        "name" : "xiaohei",
        "age" : 3
    ],
    "picture": [
        [
            "url": "這里是url",
            "name": "一張圖片"
        ],
        [
            "url": "這里是url",
            "name": "一張圖片"
        ]
    ]
]
  • 根據(jù)數(shù)據(jù), 定義三個(gè)類: Person, Pet, Picture, 每個(gè)類都遵守Codable協(xié)議
class Person: Codable {
    var name: String?
    var age: Int?
    var h: Double?
    var pet: Pet?
    var picture: [Picture]?
    
    private enum CodingKeys: String, CodingKey {
        case h = "height"
        case name
        case age
        case pet
        case picture
    }
}

class Pet: Codable {
    var name: String?
    var age: Int?
}

class Picture: Codable {
    var url: String?
    var name: String?
}
  • Person類中有如下代碼, 表示屬性h接收J(rèn)SON數(shù)據(jù)中的height字段對應(yīng)的值
    private enum CodingKeys: String, CodingKey {
        case h = "height"
        case name
        case age
        case pet
        case picture
    }
  • 定義字典轉(zhuǎn)模型方法, 這里使用了泛型
func JSONModel<T>(_ type: T.Type, withKeyValues data:[String:Any]) throws -> T where T: Decodable {
    let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
    let model = try JSONDecoder().decode(type, from: jsonData)
    return model
}
  • 調(diào)用字典轉(zhuǎn)模型方法
if let p = try? JSONModel(Person.self, withKeyValues: dict) {
    print(p.name, p.h, p.age)
    print(p.pet?.name, p.pet?.age)
    print(p.picture?.first?.url, p.picture?.first?.name)
}
// 控制臺打印: 
Optional("zhangsan") Optional(1.8799999999999999) nil
Optional("xiaohei") Optional(3)
Optional("這里是url") Optional("一張圖片")

這里類的所有屬性都是可選類型, 這是因?yàn)楫?dāng)類中的屬性, 在JSON數(shù)據(jù)中沒有對應(yīng)key時(shí),
1、如果屬性非可選, 就會轉(zhuǎn)模型失敗
2、如果屬性可選, 這個(gè)屬性就不會被賦值, 并且模型轉(zhuǎn)換成功

二、數(shù)組轉(zhuǎn)模型數(shù)組

  • 現(xiàn)有如下JSON數(shù)組
let list: [[String:Any]] = [
    [
        "name" : "zhangsan",
        "age" : 20
    ],
    [
        "name" : "lisi",
        "age" : 18
    ],
    [
        "name" : "wangwu",
        "age" : 25
    ]
]
  • 定義數(shù)組轉(zhuǎn)模型數(shù)組方法
func JSONModels<T>(_ type: T.Type, withKeyValuesArray datas: [[String:Any]]) throws -> [T]  where T: Decodable {
    var temp: [T] = []
    for data in datas {
        let model = try JSONModel(type, withKeyValues: data)
        temp.append(model)
    }
    return temp
}
  • 調(diào)用數(shù)組轉(zhuǎn)模型數(shù)組方法
if let ps = try? JSONModels(Person.self, withKeyValuesArray: list) {
    for p in ps {
        print(p.name, p.age)
    }
}
// 控制臺打印:
Optional("zhangsan") Optional(20)
Optional("lisi") Optional(18)
Optional("wangwu") Optional(25)

三、上面用到的兩個(gè)方法

/// 字典 -> 模型
///
/// - Parameters:
///   - type: 類型
///   - data: 字典數(shù)據(jù)
/// - Returns: 模型結(jié)果
/// - Throws: 錯誤處理
func JSONModel<T>(_ type: T.Type, withKeyValues data:[String:Any]) throws -> T where T: Decodable {
    let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
    let model = try JSONDecoder().decode(type, from: jsonData)
    return model
}

/// 字典數(shù)組 -> 模型數(shù)組
///
/// - Parameters:
///   - type: 類型
///   - datas: 字典組數(shù)
/// - Returns: 模型數(shù)組結(jié)果
/// - Throws: 錯誤處理
func JSONModels<T>(_ type: T.Type, withKeyValuesArray datas: [[String:Any]]) throws -> [T]  where T: Decodable {
    var temp: [T] = []
    for data in datas {
        let model = try JSONModel(type, withKeyValues: data)
        temp.append(model)
    }
    return temp
}
最后編輯于
?著作權(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ā)布平臺,僅提供信息存儲服務(wù)。

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

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