美文网首页
Swift-转模型HandyJSON

Swift-转模型HandyJSON

作者: 物非0人非 | 来源:发表于2022-05-31 16:19 被阅读0次
    • 一 简介

    • 二 特性

    • 三 安装使用以及封装

    • 四 使用示例

    一 简介

    HandyJSON是一个用于Swift语言中的JSON序列化/反序列化库。

    与其他流行的Swift JSON库相比,HandyJSON的特点是,它支持纯swift类,使用也简单。它反序列化时(把JSON转换为Model)不要求ModelNSObject继承(因为它不是基于KVC机制),也不要求你为Model定义一个Mapping函数。只要你定义好Model类,声明它服从HandyJSON协议,HandyJSON就能自行以各个属性的属性名为Key,从JSON串中解析值。

    HandyJSON目前依赖于从Swift Runtime源码中推断的内存规则,任何变动我们将随时跟进。

    二 特性

    • 序列化ModelJSON、从JSON反序列化Model
    • 自然地以Model的属性名称作为解析JSONKey,不需要额外指定
    • 支持Swift中大部分类型
    • 支持classstruct定义的Model
    • 支持自定义解析规则
    • 类型自适应,如JSON中是一个Int,但对应ModelString字段,会自动完成转化

    三 安装使用以及封装

    3.1 安装
    我使用的是cocopod进行包引入管理,修改Prodfie文件,添加如下代码:

    pod 'HandyJSON'
    

    3.2 封装
    为了方便我们项目中的使用,我们一般都会在做一层封装,方便库的以后升级替换,以及方便日常业务逻辑的处理

    JsonUtil.swift
     
    import UIKit
    import HandyJSON
    class JsonUtil: NSObject {
        /**
         *  Json转对象
         */
        static func jsonToModel(_ jsonStr:String,_ modelType:HandyJSON.Type) ->BaseModel {
            if jsonStr == "" || jsonStr.count == 0 {
                #if DEBUG
                    print("jsonoModel:字符串为空")
                #endif
                return BaseModel()
            }
            return modelType.deserialize(from: jsonStr)  as! BaseModel
            
        }
        
        /**
         *  Json转数组对象
         */
        static func jsonArrayToModel(_ jsonArrayStr:String, _ modelType:HandyJSON.Type) ->[BaseModel] {
            if jsonArrayStr == "" || jsonArrayStr.count == 0 {
                #if DEBUG
                    print("jsonToModelArray:字符串为空")
                #endif
                return []
            }
            var modelArray:[BaseModel] = []
            let data = jsonArrayStr.data(using: String.Encoding.utf8)
            let peoplesArray = try! JSONSerialization.jsonObject(with:data!, options: JSONSerialization.ReadingOptions()) as? [AnyObject]
            for people in peoplesArray! {
                modelArray.append(dictionaryToModel(people as! [String : Any], modelType))
            }
            return modelArray
            
        }
        
        /**
         *  字典转对象
         */
        static func dictionaryToModel(_ dictionStr:[String:Any],_ modelType:HandyJSON.Type) -> BaseModel {
            if dictionStr.count == 0 {
                #if DEBUG
                    print("dictionaryToModel:字符串为空")
                #endif
                return BaseModel()
            }
            return modelType.deserialize(from: dictionStr) as! BaseModel
        }
        
        /**
         *  对象转JSON
         */
        static func modelToJson(_ model:BaseModel?) -> String {
            if model == nil {
                #if DEBUG
                    print("modelToJson:model为空")
                #endif
                 return ""
            }
            return (model?.toJSONString())!
        }
        
        /**
         *  对象转字典
         */
        static func modelToDictionary(_ model:BaseModel?) -> [String:Any] {
            if model == nil {
                #if DEBUG
                    print("modelToJson:model为空")
                #endif
                return [:]
            }
            return (model?.toJSON())!
        }
        
    }
    

    说明:这里我封装了5个方法,Json转对象,Json数组对象字典对象对象JSON对象字典,基本覆盖了我们日常开发的常用操作,与这个工具类相对应的,还有一个公共的基础module

    BaseModel.swift
     
    import UIKit
    import HandyJSON
    class BaseModel: HandyJSON {
    //    var date: Date?
    //    var decimal: NSDecimalNumber?
    //    var url: URL?
    //    var data: Data?
    //    var color: UIColor?
        
        required init() {}
        
        func mapping(mapper: HelpingMapper) {   //自定义解析规则,日期数字颜色,如果要指定解析格式,子类实现重写此方法即可
    //        mapper <<<
    //            date <-- CustomDateFormatTransform(formatString: "yyyy-MM-dd")
    //
    //        mapper <<<
    //            decimal <-- NSDecimalNumberTransform()
    //
    //        mapper <<<
    //            url <-- URLTransform(shouldEncodeURLString: false)
    //
    //        mapper <<<
    //            data <-- DataTransform()
    //
    //        mapper <<<
    //            color <-- HexColorTransform()
          }
    }
    

    说明:封装的基础model类。开发中,我们自定义的model继承此model即可省去了每次都要引入 “import HandyJSON”,以及每次都要实现“required init() {}”方法,子类如果要自定义解析规则,重写mapping方法即可

    四 使用示例

    基于以上封装的类我们实现几个示例做具体说明,主要有以下几个示例:

    • Json转模型 (常用)
    • Json数组转模型 (常用)
    • 字典转模型
    • 模型转Json
    • 模型转字典
    • json与嵌套的模型相互转换特殊类型字段转换,日期类型,数字类型,颜色
    1. Json转模型 (常用)
    JsonToModel.swift
     
    import UIKit
    class JsonToModel: BaseModel {
        var id :Int?
        var color:String?
        var name:String?
    }
     fileprivate func jsonTomodel(){
            let jsonString = "{\"id\":12345,\"color\":\"black\",\"name\":\"cat\"}"
            let model:JsonToModel = JsonUtil.jsonToModel(jsonString,JsonToModel.self) as! JsonToModel
            print(model.name as Any)
            print(model.color as Any)
            print(model.id as Any)
        }
    

    说明:调用jsonToModel(_ jsonStr:String,_ modelType:HandyJSON.Type),传入两个参数,第一个参数是要转换的Json字符串,第二个参数是要转换的model类的class,因为公共类中统一返回的都是BaseModel类型,所以这里要调用 as!转换成具体的子类类型。

    2. Json数组转模型 (常用)
    JsonArrayToModel.swift
     
    import UIKit
    class JsonArrayToModel: BaseModel {
        var name:String?
        var id :String?
    }
    //json数组转模型
        fileprivate func jsonArrayTomodel() {
            let jsonArrayString: String = "[{\"name\":\"Bob\",\"id\":\"1\"}, {\"name\":\"Lily\",\"id\":\"2\"}, {\"name\":\"Lucy\",\"id\":\"3\"}]"
            let cats = JsonUtil.jsonArrayToModel(jsonArrayString, JsonArrayToModel.self) as! [JsonArrayToModel]
            for model:JsonArrayToModel  in cats {
                print(model.name as Any)
            }
        }
    

    说明:调用jsonArrayToModel(_ jsonArrayStr:String, _ modelType:HandyJSON.Type)传入两个参数,第一个参数是要转换的数组型Json字符串,第二个参数是要转换的model类的class,返回值是一个数组,因为公共类中统一返回的都是BaseModel类型,所以这里要调用as!转换成具体的子类类型数组。

    3 字典转模型
    import UIKit
    class JsonToModel: BaseModel {
        var id :Int!
        var color:String?
        var name:String?
    }
    //字典转模型
        fileprivate func dicToModel() {
            var dict = [String: Any]()
            dict["id"] = 1.1
            dict["color"] = "hello"
            dict["name"] = "李四"
            let model:JsonToModel = JsonUtil.dictionaryToModel(dict,JsonToModel.self) as! JsonToModel
            print(model.name as Any)
            print(model.color as Any)
            print(model.id as Any)
        }
    

    说明:调用dictionaryToModel(_ dictionStr:[String:Any],_ modelType:HandyJSON.Type),传入两个参数,第一个参数是要转换的字典对象,第二个参数是要转换的model类的class,因为公共类中统一返回的都是BaseModel类型,所以这里要调用as!转换成具体的子类类型。

    4. 模型转Json
    JsonToModel.swift
     
    import UIKit
    class JsonToModel: BaseModel {
        var id :Int!
        var color:String?
        var name:String?
    }
    //模型转json
        fileprivate func modelToJson() {
            let model:JsonToModel = JsonToModel()
            model.color = "red"
            model.id    = 100
            model.name  = "李四真"
            let modelTostring = JsonUtil.modelToJson(model)
            print(modelTostring)
        }
    

    说明:调用modelToJson(_ model:BaseModel?),传入一个参数,传入一个module对象,返回值是一个JSON字符串

    5. 模型转字典
    JsonToModel.swift
    
    import UIKit
    class JsonToModel: BaseModel {
        var id :Int!
        var color:String?
        var name:String?
    }
     //模型转字典
        fileprivate func modelTodiction() {
            let model:JsonToModel = JsonToModel()
            model.color = "red"
            model.id    = 100
            model.name  = "李四"
            let modelTostring = JsonUtil.modelToDictionary(model)
            print(modelTostring["name"] as Any)
            
        }
    

    说明:调用modelToDictionary(_ model:BaseModel?)传入一个参数,传入一个module对象,返回值是一个字典对象,对于日常开发中,有时候后台只返回一个字段,比如返回一个成功信息字段,直接把返回的json串转换成一个字典即可,没必要再构建一个model去转换。

    6. json与嵌套的模型相互转换
    CombineModel.swift
     
    import UIKit
    class Composition:  BaseModel {
        var aInt:Int?
        var aString:String?
    }
     
    class CombineModel: BaseModel {
        var aInt:Int?
        var comp1:Composition?
        var comp2:[Composition] = []
        
    }
    //json与嵌套的模型相互转换
        fileprivate func jsonTocombilModel() {
            let model:CombineModel = CombineModel()
            model.aInt = 1001
            let posModel1 = Composition()
            posModel1.aInt = 1
            posModel1.aString = "赵六1"
            
            let posModel2 = Composition()
            posModel2.aInt = 2
            posModel2.aString = "赵六2"
            
            let posModel3 = Composition()
            posModel3.aInt = 3
            posModel3.aString = "赵六3"
            
            model.comp1 = posModel1
            model.comp2.append(posModel2)
            model.comp2.append(posModel3)
            
            let modeString = JsonUtil.modelToJson(model)
            print(modeString)
            
            let model2 = JsonUtil.jsonToModel(modeString, CombineModel.self)
            print(model2)
        }
    

    说明:还是调用Json转模型,模型转Json的方法,本例子演示的是对象嵌套,对象里面可以嵌套对象,可以嵌套对象数组,平时我们开发经常遇到这种结构的Json串

    7. 特殊类型字段转换,日期类型,数字类型,颜色
    SpacialTypeModel.swift
     
    import UIKit
    import HandyJSON
    class SpacialTypeModel: BaseModel {
        var date: Date?
        var decimal: NSDecimalNumber?
        var url: URL?
        var data: Data?
        var color: UIColor?
        
        override func mapping(mapper: HelpingMapper) {
            mapper <<< 
                date <-- CustomDateFormatTransform(formatString: "yyyy-MM-dd")
     
            mapper <<<
                decimal <-- NSDecimalNumberTransform()
     
            mapper <<<
                url <-- URLTransform(shouldEncodeURLString: false)
     
            mapper <<<
                data <-- DataTransform()
     
            mapper <<<
                color <-- HexColorTransform()
        }
     
    }
    // 特殊类型字段转换,日期类型,数字类型,颜色
        fileprivate func jsonToSpecialModel () {
            
            let object = SpacialTypeModel()
            object.date = Date()
            object.decimal = NSDecimalNumber(string: "1.23423414371298437124391243")
            object.url = URL(string: "https://www.aliyun.com")
            object.data = Data(base64Encoded: "aGVsbG8sIHdvcmxkIQ==")
            object.color = UIColor.blue
            
            let specailModelString = JsonUtil.modelToJson(object)
            print(object.toJSONString()!)
            // it prints:
            // {"date":"2017-09-11","decimal":"1.23423414371298437124391243","url":"https:\/\/www.aliyun.com","data":"aGVsbG8sIHdvcmxkIQ==","color":"0000FF"}
            
            let mappedObject:SpacialTypeModel = JsonUtil.jsonToModel(specailModelString, SpacialTypeModel.self) as! SpacialTypeModel
            print(mappedObject.date as Any)
        }
    

    说明:本例演示的是对于对象里含有特殊类型字段的转换方法,主要注意点在构建model类里,我们要重写父类mapping方法还要引入HandyJSON头文件

    相关文章

      网友评论

          本文标题:Swift-转模型HandyJSON

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