- 一 简介
- 二 特性
- 三 安装利用以及封装
- 四 利用示例
- 五 项目利用示例
一 简介
HandyJSON是一个用于Swift语言中的JSON序列化/反序列化库。
与其他盛行的Swift JSON库相比,HandyJSON的特点是,它支持纯swift类,利用也简朴。它反序列化时(把JSON转换为Model)不要求Model从NSObject继承(由于它不是基于KVC机制),也不要求你为Model界说一个Mapping函数。只要你界说好Model类,声明它服从HandyJSON协议,HandyJSON就能自行以各个属性的属性名为Key,从JSON串中分析值。
HandyJSON现在依赖于从Swift Runtime源码中推断的内存规则,任何变更我们将随时跟进。
二 特性
- 序列化Model到JSON、从JSON反序列化到Model
- 天然地以Model的属性名称作为分析JSON的Key,不必要额外指定
- 支持Swift中大部分范例
- 支持class、struct界说的Model
- 支持自界说分析规则
- 范例自顺应,如JSON中是一个Int,但对应Model是String字段,会自动完成转化
三 安装利用以及封装
3.1 安装
我利用的是cocopod举行包引入管理,修改Prodfie文件,添加如下代码:
pod 'HandyJSON'3.2 封装
为了方便我们项目中的利用,我们一样平常都会在做一层封装,方便库的以后升级更换,以及方便一样平常业务逻辑的处理
JsonUtil.swift import UIKitimport HandyJSONclass 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 UIKitimport HandyJSONclass 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 UIKitclass 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 UIKitclass 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 UIKitclass 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 UIKitclass 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.swiftimport UIKitclass 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 UIKitclass 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 UIKitimport HandyJSONclass 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头文件
五 项目利用示例
// MARK: - 基类模子转模子为返回范例为[String:Any]public struct DailyStudyBaseModel<T>:HandyJSON { public var code: Int? public var msg: String? public var msgDetail: String? public var data: T? public init() { } }// MARK: - 基类模子转模子为返回范例为[[String:Any]]public struct DailyStudyBaseListModel<T>:HandyJSON { public var code: Int? public var msg: String? public var msgDetail: String? public var data: [T]? public init() { }}// MARK: - 基类模子转模子为返回范例为bool 或者是 其他的 public struct DailyStudyBaseResultModel:HandyJSON { public var code: Int? public var msg: String? public var msgDetail: String? public var data: Any? public init() { }}// MARK: - 处理分页查询返回的模子public struct SDBasePageModel<T:HandyJSON>: HandyJSON { public var pageNum: Int? public var hasNextPage: Bool? public var list :[T]? public init() { }}import Foundationimport SDBasicProjectlet width = (SDJG_ScreenWidth - 20 - 18 - 18 - 40) / 3class JHAdressModel: HandyJSON { var title : String = "" var list: [JHAdressCityModel] = [] required init() { }}class JHAdressCityModel: HandyJSON { var c_province : String = "" var c_pinyin : String = "" var c_code : String = "" var selected: Bool = false// var label : String = "" var value : String = "" var height: CGFloat = 0.0 required init() { } var label: String? { didSet{ let liveNameHeight = self.label?.extGetHeightByWidth(with: self.label ?? "" , width: width, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: SDAuRate(value: 17), weight: .medium)]) self.height = 8 + (liveNameHeight ?? 0) + 8 } }}//赋值 public var model: JHAdressCityModel? { didSet{ nameLabel.text = model?.label ?? "" if model?.label?.isEmpty == true{ self.layer.borderColor = UIColor.clear.cgColor self.backgroundColor = .clear self.isUserInteractionEnabled = false }else{ self.isUserInteractionEnabled = true if model?.selected == true { nameLabel.textColor = .extColorWithHex("#E72026") self.backgroundColor = .extColorWithHex("#FFE3E1") self.layer.borderColor = UIColor.extColorWithHex("#E72227").cgColor }else{ nameLabel.textColor = .extColorWithHex("#333333") self.backgroundColor = .extColorWithHex("#F7F7F7") self.layer.borderColor = UIColor.extColorWithHex("#F7F7F7").cgColor } } } } //// JHGoldMoldel.swift// SDHuaYangFriendProject//// Created by JH on 2023/1/10.//import Foundationimport SDBasicProjectclass JHGoldMoldel: HandyJSON { var creditNum: String? //当前金币数量 // 列表数据 var productList: [JHGoldProductMoldel] = [] required init() { }}class JHGoldProductMoldel: HandyJSON { var productSkuId: String? //商品ID var availableCredit: String?//可获得金币 var salePrice:String? //商品代价 var selected: Bool = false required init() { }}class JHGoldOrderMoldel: HandyJSON { var orderNo: String? //商品ID required init() { }}class JHGoldDesMoldel: HandyJSON { var amount: String? var createTime: String? var eventName:String? var remark: String? var type: String? var totalAmount: String? required init() { }}//// StationModel.swift// SDPatternStationProject//// Created by lanlan on 2022/3/9.//import SDBasicProject// MARK: - 站长列表class StationMasterList :HandyJSON { ///小站名称 var siteName:String = "" ///站长名称 var masterName:String = "" ///站长头像 var headImgUrl:String = "" ///站长主键 var id:Int = 0 ///是否有直播标记 0: 没有 1:有 var liveFlag:Bool = false ///站长品级 0: 金牌站长 var level:Int = 0 ///个人简介 var personalProfile:String = "" /// 关注数量 var attentionNum:Int = 0 /// 关注数量格式化 var formatAttentionNum:String = "" /// 点赞数量 var thumbNum:Int = 0 ///格式化点赞数量 var formatThumbNum:String = "" ///0: 未置顶 1:置顶 var stickieType:Bool = false ///0:未关注 1:已关注 var attentionType:Bool = false //默认选中 var isSeleted = false required init() { } func didFinishMapping() { formatAttentionNum = formatDecimals(num: attentionNum, separate: 10000) formatThumbNum = formatDecimals(num: thumbNum, separate: 10000) } public func formatDecimals(num:Int,separate:Int) -> String { if num < 10000 { return "\(num)" } let intVal = num / separate let doubleVal = num % separate let suffixValue = doubleVal / 1000 if suffixValue == 0 { return "\(intVal)w+" } return "\(intVal).\(suffixValue)w+" }}struct StationMasterDetailModel :HandyJSON { var course:StationMasterDetailCourseModel? var groupInfo:StationMasterDetailGroupInfoModel? //站长信息 当地带的 var siteInfo:StationMasterList? //关注人数 var memberNum:Int = 0 ///关注状态 var attentionType:Bool = false}struct StationMasterDetailGroupInfoModel :HandyJSON { var itemImGroup:[StationMasterDetailGroupModel]? var publicImGroup:StationMasterDetailGroupModel?}struct StationMasterDetailCourseModel :HandyJSON { var courseFlag:Int = 0 var courseId:String = "" var coverPic:String = "" var headImgUrl:String = "" var lecturerName:String = "" var liveId:Int = 0 var liveName:String = "" var liveStartTime:Int = 0 var liveStatus:Int = 0 var siteId:Int = 0 var skuId:Int = 0 var skuName:String = "" var videoType:Int = 0 }struct StationMasterDetailGroupModel :HandyJSON { var imGroupId:String = "" var imGroupName:String = "" //0:加锁 1:解锁 var lockStatus:Int = 0 ///商城必要的id var productSpuId:Int = 0 var productSkuId:Int = 0 var siteId:String = "" var subBrandId:String = "" var distributeSubBrandId:String = "" } |