美文网首页swift
Swift4: Codable->字典转模型的具体实现

Swift4: Codable->字典转模型的具体实现

作者: 伯wen | 来源:发表于2018-07-20 15:25 被阅读836次

    一、字典转模型

    • 现有如下JSON数据
    let dict: [String : Any] = [
        "name" : "zhangsan",
        "height" : 1.88,
        "pet" : [
            "name" : "xiaohei",
            "age" : 3
        ],
        "picture": [
            [
                "url": "这里是url",
                "name": "一张图片"
            ],
            [
                "url": "这里是url",
                "name": "一张图片"
            ]
        ]
    ]
    
    • 根据数据, 定义三个类: Person, Pet, Picture, 每个类都遵守Codable协议
    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接收JSON数据中的height字段对应的值
        private enum CodingKeys: String, CodingKey {
            case h = "height"
            case name
            case age
            case pet
            case picture
        }
    
    • 定义字典转模型方法, 这里使用了泛型
    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
    }
    
    • 调用字典转模型方法
    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("一张图片")
    

    这里类的所有属性都是可选类型, 这是因为当类中的属性, 在JSON数据中没有对应key时,
    1、如果属性非可选, 就会转模型失败
    2、如果属性可选, 这个属性就不会被赋值, 并且模型转换成功

    二、数组转模型数组

    • 现有如下JSON数组
    let list: [[String:Any]] = [
        [
            "name" : "zhangsan",
            "age" : 20
        ],
        [
            "name" : "lisi",
            "age" : 18
        ],
        [
            "name" : "wangwu",
            "age" : 25
        ]
    ]
    
    • 定义数组转模型数组方法
    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
    }
    
    • 调用数组转模型数组方法
    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)
    

    三、上面用到的两个方法

    /// 字典 -> 模型
    ///
    /// - Parameters:
    ///   - type: 类型
    ///   - data: 字典数据
    /// - Returns: 模型结果
    /// - 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
    }
    
    /// 字典数组 -> 模型数组
    ///
    /// - Parameters:
    ///   - type: 类型
    ///   - datas: 字典组数
    /// - Returns: 模型数组结果
    /// - 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
    }
    

    相关文章

      网友评论

        本文标题:Swift4: Codable->字典转模型的具体实现

        本文链接:https://www.haomeiwen.com/subject/hcqqmftx.html