Json转模型1--SwiftyJson
JSON是移动端开发常用的应用层数据交换协议。最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上。 但在编程的时候,处理JSON是一件麻烦事。在不引入任何轮子的情况下,我们通常需要先把JSON转为Dictionary,然后还要记住每个数据对应的Key,用这个Key在Dictionary中取出对应的Value来使用。这个过程我们会犯各种错误:
* Key拼写错了
* 路径写错了
* 类型搞错了
* 没拿到值懵逼了
* 某一天和服务端约定的某个字段变更了,没能更新所有用到它的地方
* ...
为了解决这些问题,很多处理JSON的开源库应运而生。在Swift中,这些开源库主要朝着两个方向努力:
1. 保持JSON语义,直接解析JSON,但通过封装使调用方式更优雅、更安全
2. 预定义Model类,将JSON反序列化为类实例,再使用这些实例
对于1,使用最广、评价最好的库非 SwiftyJSON 莫属,它很能代表这个方向的核心。它本质上仍然是根据JSON结构去取值,使用起来顺手、清晰。但也正因如此,这种做法没能妥善解决上述的几个问题,因为Key、路径、类型仍然需要开发者去指定;
对于2,我个人觉得这是更合理的方式。由于Model类的存在,JSON的解析和使用都受到了定义的约束,只要客户端和服务端约定好了这个Model类,客户端定义后,在业务中使用数据时就可以享受到语法检查、属性预览、属性补全等好处,而且一旦数据定义变更,编译器会强制所有用到的地方都改过来才能编译通过,非常安全。这个方向上,开源库们做的工作,主要就是把JSON文本反序列化到Model类上了。这一类JSON库有 ObjectMapper、JSONNeverDie、HandyJSON 等。
今天我们先来看看SwiftyJSON的用法。
通常我们拿到数据会进行非常麻烦的optinonal(可选类型)进行拆包(Wrapping )操作,
SwiftyJson内部会自动对optional进行拆包,大大简化了代码,解析非常方便,拿到的json数据data直接扔进去
//转成JSON对象
let jsonData = JSON.init(data)
不管需要什么数据只要通过对jsonData
进行路径读取
例如:
let build_name = jsonData[0]["build_name"].stringValue
值得一提的是,不需要考虑服务器给我们返回的是什么类型,比如去请求一个房屋的栋数"build_num": 588
我们想要获得Int类型或者String类型都可以
let room_num1 = jsonData[0]["build_num"].stringValue
let room_num2 = jsonData[0]["build_num"].intValue
// room_num1 = 588 String类型
// room_num2 = 588 Int类型
这样通过.stringValue
.intValue
就可以获得不可选值类型,如果没有获取到数据的话就会返回一个默认值即.stringValue
获得空字符串""
,.intValue
得到0
,.arrayValue
获得空数组[]
,我们就不用判断拆包了。
当然某些场景可能需要你得到可选值类型并自己判断是否存在,那么我们可以通过.string .int .bool .float .array .dictionary
等等方法获取,例如:
//String
if let build_name = jsonData[0]["build_name"].string {print(build_name)
} else {//打印错误信息print(jsonData[0]["build_name"])
}
解析数据是真的非常简单。详细使用可以看看SwiftyJSON的使用详解(附样例)
或者移步GitHub-SwiftyJson
但是对于项目而言我们需要对数据进行转换为模型,仅仅是对data进行JSON读取是远远不够的,想想,如果遇到许多地方都用到了build_name
值,但是当服务器给我们返回的字段名字改了,我们改项目时就会显得麻烦,甚至造成改不完全,所以我们队数据封装一下转为模型,这样修改时只用改一个地方就是model的赋值就好了。
那我的方法是:
//这是模拟数据
let baseInfo: [String : Any] = ["build_name":"置信·原墅","build_address":"学院中路与金桥路交汇处东北侧","build_num": 12,"room_num": 588,"area_address":"浙江省温州市鹿城区五马街道"]
创建struct模型,当然Class也可以,但是如果不需要继承也不复杂推荐struct(-。-不多解释了)
并写好创建方法
import SwiftyJSONstruct BuildBaseInfoModel {var build_name: String?var build_address: String?var build_num: String?var room_num: String?var area_address: String?init(jsonData: JSON) {build_name = jsonData["build_name"].stringValuebuild_address = jsonData["build_address"].stringValuearea_address = jsonData["area_address"].stringValueroom_num = jsonData["room_num"].stringValuebuild_num = jsonData["build_num"].stringValue}
}
调用:
let jsonData = JSON(baseInfo)
let model = BuildBaseInfoModel.init(jsonData: jsonData)
// 会得到创建好的 BuildBaseInfoModel类型的 对象model
// 也可以这样写
let model = BuildBaseInfoModel(jsonData: jsonData)
当然这只是普通的模型,经常会遇到复杂模型,例如:
// 面积中89是Int, 109和129是String
let baseInfo: [String : Any] = ["build_name":"置信·原墅","build_address":"学院中路与金桥路交汇处东北侧","area_address":"浙江省温州市鹿城区五马街道","area":[89,"109","129"],"detail_address":["province":"浙江省","city":"温州市","district":"鹿城区","street":"五马街道"],"build_num": 12,"room_num": 588]
这时候模型就应该有两个
struct BuildBaseInfoModel {var build_name: String?var build_address: String?var build_num: String?var room_num: String?var area_address: String?var detail_address: DetailAddressModelvar area:[Any]?// 这里面积area中就不能再用arrayValue获取了,因为arrayValue获取的为JSON类型,我们需要转为我们需要的对象init(jsonData: JSON) {build_name = jsonData["build_name"].stringValuebuild_address = jsonData["build_address"].stringValuearea_address = jsonData["area_address"].stringValueroom_num = jsonData["room_num"].stringValuebuild_num = jsonData["build_num"].stringValuearea = jsonData["area"].arrayObjectdetail_address = DetailAddressModel(jsonData: jsonData["detail_address"])}
}
struct DetailAddressModel {var province: String?var city: String?var district: String?var street: String?init(jsonData: JSON) {province = jsonData["province"].stringValuecity = jsonData["city"].stringValuedistrict = jsonData["district"].stringValuestreet = jsonData["street"].stringValue}}
let model = BuildBaseInfoModel(jsonData: jsonData)
DPrint(message: model.detail_address.city)
DPrint(message: model.area?.first)
DPrint(message: model.area?[1])
// xxxxxxxxx.swift[21], updateRoomsData(index:): Optional("温州市")
// xxxxxxxxx.swift[22], updateRoomsData(index:): Optional(89)
// xxxxxxxxx.swift[22], updateRoomsData(index:): Optional("109")
好了,完成,虽然解析Json数据非常方便,但是创建模型的时候,还是略显繁琐。不过不管怎么说目的达到了
作者:JoeXP链接:http://www.jianshu.com/p/46f55c2d219c來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Json转模型1--SwiftyJson相关推荐
- IOS开发基础之网易新闻JSON转模型数组第2天
IOS开发基础之网易新闻JSON转模型数组第2天 // // HMHeadline.h // 01-网易新闻搭建 // // Created by 鲁军 on 2021/4/11. //#import ...
- YYModel之字典/Json转模型
从事iOS工作也有两年多了.iOS开发就更久了.说到转模型还是比较喜欢用YYModel框架.当然,期间也用过MJExtension等三方转模型框架. 为什么都喜欢转模型.最开始使用YYModel的时候 ...
- Swift JSON与模型转换(HandyJSON封装)
2018.05.02 20:20:16字数 1,493阅读 5,017 一 简介 二 特性 三 安装使用以及封装 四 使用示例 五 总结 一 简介 HandyJSON是一个用于Swift语言中的JSO ...
- Swift JSON转模型Xcode插件
SwiftJSONModeler是一个Xcode插件,一键转换json字符串为Swfit模型,一键转化 YApi 平台接口为模型,并且自动引入注释. 支持struct, class 支持单json转模 ...
- iOS 在线JSON转模型工具(Swift、Objective-C、Java)
JSON数据自动转模型,帮助有大量模型数据处理的朋友加快开发速度. 链接:https://www.vfun.fun/pages/tools-page/JsonToFile/index.html
- JSON转模型归档与解档
1.用户账户模型类 UserAccount.swift ///用户账户模型 class UserAccount: NSObject, NSCoding{//用户授权的唯一票据,用于调用微博的开放接口, ...
- json转换模型利器--JSONExport
JSONExport 从json 到 Model ,如此的方便 swift oc java 全部支持
- 2.1、用JsonParser解析json树模型
解析json字符串可以像解析DOM一样,解析每一个节点.Gson的jar包中提供了JsonParser类,专门用于解析json字符串的,注意只是json节点的内容解析出来,并不像前两节把整个json字 ...
- 用JsonParser解析json树模型
解析json字符串可以像解析DOM一样,解析每一个节点.Gson的jar包中提供了JsonParser类,专门用于解析json字符串的,注意只是json节点的内容解析出来,并不像前两节把整个json字 ...
最新文章
- 2016江苏计算机二级考试时间,2016年江苏计算机二级考试报名时间_无忧考网.pdf...
- Waymo自动驾驶汽车扎堆冲进死胡同,一天多达50辆,附近居民蚌埠住了
- 特征值 与特征向量(机器学习算法原理与实践)
- 十大迷你iPhone天气应用
- RFID助力汽车零部件厂商识别冲压工具位置
- VTK:图片之ImageRotate
- html输出text,为什么text();和html();输出结果不一样呢?
- 转: Div与table的区别
- CF364B. Free Market
- 不同维度的矩阵相乘的时间复杂度
- 百度安全DDoS攻击年度报告出炉 企业防护有新招!
- unity3D 实战 《小十传奇》系列之三:控制层(下)
- java泛型,“参数化参数”的基本理解
- 拓端tecdat|R语言主成分分析(PCA)葡萄酒可视化:主成分得分散点图和载荷图
- 论文解读|BMVC 2019 |Fast-SCNN Fast Semantic Segmentation Network
- IMDB TOP250 更新于2015.3
- 优秀程序员的博客有哪些?(2021 年 3 月版)
- DOTA数据集应用于Yolo-v4(-Tiny)系列2——使用Pytorch框架的Yolov4(-Tiny)训练与推测
- 1.1.24 制作红头文件
- 【Android】自定义FlowLayout,支持多种布局优化--android-flowlayout