JSON是移动端开发常用的应用层数据交换协议。最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上。
但在编程的时候,处理JSON是一件麻烦事。在不引入任何轮子的情况下,我们通常需要先把JSON转为Dictionary,然后还要记住每个数据对应的Key,用这个Key在Dictionary中取出对应的Value来使用。这个过程我们会犯各种错误:

  1. * Key拼写错了

  2. * 路径写错了

  3. * 类型搞错了

  4. * 没拿到值懵逼了

  5. * 某一天和服务端约定的某个字段变更了,没能更新所有用到它的地方

  6. * ...

为了解决这些问题,很多处理JSON的开源库应运而生。在Swift中,这些开源库主要朝着两个方向努力:

  1. 1. 保持JSON语义,直接解析JSON,但通过封装使调用方式更优雅、更安全

  2. 2. 预定义Model类,将JSON反序列化为类实例,再使用这些实例

对于1,使用最广、评价最好的库非 SwiftyJSON 莫属,它很能代表这个方向的核心。它本质上仍然是根据JSON结构去取值,使用起来顺手、清晰。但也正因如此,这种做法没能妥善解决上述的几个问题,因为Key、路径、类型仍然需要开发者去指定;

对于2,我个人觉得这是更合理的方式。由于Model类的存在,JSON的解析和使用都受到了定义的约束,只要客户端和服务端约定好了这个Model类,客户端定义后,在业务中使用数据时就可以享受到语法检查、属性预览、属性补全等好处,而且一旦数据定义变更,编译器会强制所有用到的地方都改过来才能编译通过,非常安全。这个方向上,开源库们做的工作,主要就是把JSON文本反序列化到Model类上了。这一类JSON库有 ObjectMapper、JSONNeverDie、HandyJSON 等。

今天我们先来看看SwiftyJSON的用法。

通常我们拿到数据会进行非常麻烦的optinonal(可选类型)进行拆包(Wrapping )操作,
SwiftyJson内部会自动对optional进行拆包,大大简化了代码,解析非常方便,拿到的json数据data直接扔进去

  1. //转成JSON对象

  2. let jsonData = JSON.init(data)

不管需要什么数据只要通过对jsonData进行路径读取
例如:

let build_name = jsonData[0]["build_name"].stringValue

值得一提的是,不需要考虑服务器给我们返回的是什么类型,比如去请求一个房屋的栋数"build_num": 588我们想要获得Int类型或者String类型都可以

  1. let room_num1 = jsonData[0]["build_num"].stringValue

  2. let room_num2 = jsonData[0]["build_num"].intValue

  3. // room_num1 = 588 String类型

  4. // room_num2 = 588 Int类型

这样通过.stringValue.intValue就可以获得不可选值类型,如果没有获取到数据的话就会返回一个默认值即.stringValue获得空字符串"".intValue得到0.arrayValue获得空数组[],我们就不用判断拆包了。

当然某些场景可能需要你得到可选值类型并自己判断是否存在,那么我们可以通过.string .int .bool .float .array .dictionary等等方法获取,例如:

  1. //String

  2. if let build_name = jsonData[0]["build_name"].string {

  3. print(build_name)

  4. } else {

  5. //打印错误信息

  6. print(jsonData[0]["build_name"])

  7. }

解析数据是真的非常简单。详细使用可以看看SwiftyJSON的使用详解(附样例)
或者移步GitHub-SwiftyJson
但是对于项目而言我们需要对数据进行转换为模型,仅仅是对data进行JSON读取是远远不够的,想想,如果遇到许多地方都用到了build_name值,但是当服务器给我们返回的字段名字改了,我们改项目时就会显得麻烦,甚至造成改不完全,所以我们队数据封装一下转为模型,这样修改时只用改一个地方就是model的赋值就好了。

那我的方法是:

  1. //这是模拟数据

  2. let baseInfo: [String : Any] = ["build_name":"置信·原墅",

  3. "build_address":"学院中路与金桥路交汇处东北侧",

  4. "build_num": 12,

  5. "room_num": 588,

  6. "area_address":"浙江省温州市鹿城区五马街道"]

创建struct模型,当然Class也可以,但是如果不需要继承也不复杂推荐struct(-。-不多解释了)
并写好创建方法

  1. import SwiftyJSON

  2. struct BuildBaseInfoModel {

  3. var build_name: String?

  4. var build_address: String?

  5. var build_num: String?

  6. var room_num: String?

  7. var area_address: String?

  8. init(jsonData: JSON) {

  9. build_name = jsonData["build_name"].stringValue

  10. build_address = jsonData["build_address"].stringValue

  11. area_address = jsonData["area_address"].stringValue

  12. room_num = jsonData["room_num"].stringValue

  13. build_num = jsonData["build_num"].stringValue

  14. }

  15. }

调用:

  1. let jsonData = JSON(baseInfo)

  2. let model = BuildBaseInfoModel.init(jsonData: jsonData)

  3. // 会得到创建好的 BuildBaseInfoModel类型的 对象model

  4. // 也可以这样写

  5. let model = BuildBaseInfoModel(jsonData: jsonData)

当然这只是普通的模型,经常会遇到复杂模型,例如:

  1. // 面积中89是Int, 109和129是String

  2. let baseInfo: [String : Any] = ["build_name":"置信·原墅",

  3. "build_address":"学院中路与金桥路交汇处东北侧",

  4. "area_address":"浙江省温州市鹿城区五马街道",

  5. "area":[89,"109","129"],

  6. "detail_address":["province":"浙江省",

  7. "city":"温州市",

  8. "district":"鹿城区",

  9. "street":"五马街道"],

  10. "build_num": 12,

  11. "room_num": 588]

这时候模型就应该有两个

  1. struct BuildBaseInfoModel {

  2. var build_name: String?

  3. var build_address: String?

  4. var build_num: String?

  5. var room_num: String?

  6. var area_address: String?

  7. var detail_address: DetailAddressModel

  8. var area:[Any]?

  9. // 这里面积area中就不能再用arrayValue获取了,因为arrayValue获取的为JSON类型,我们需要转为我们需要的对象

  10. init(jsonData: JSON) {

  11. build_name = jsonData["build_name"].stringValue

  12. build_address = jsonData["build_address"].stringValue

  13. area_address = jsonData["area_address"].stringValue

  14. room_num = jsonData["room_num"].stringValue

  15. build_num = jsonData["build_num"].stringValue

  16. area = jsonData["area"].arrayObject

  17. detail_address = DetailAddressModel(jsonData: jsonData["detail_address"])

  18. }

  19. }

  20. struct DetailAddressModel {

  21. var province: String?

  22. var city: String?

  23. var district: String?

  24. var street: String?

  25. init(jsonData: JSON) {

  26. province = jsonData["province"].stringValue

  27. city = jsonData["city"].stringValue

  28. district = jsonData["district"].stringValue

  29. street = jsonData["street"].stringValue

  30. }

  31. }

  1. let model = BuildBaseInfoModel(jsonData: jsonData)

  2. DPrint(message: model.detail_address.city)

  3. DPrint(message: model.area?.first)

  4. DPrint(message: model.area?[1])

  5. // xxxxxxxxx.swift[21], updateRoomsData(index:): Optional("温州市")

  6. // xxxxxxxxx.swift[22], updateRoomsData(index:): Optional(89)

  7. // xxxxxxxxx.swift[22], updateRoomsData(index:): Optional("109")

SwiftyJson 实现Json转模型相关推荐

  1. IOS开发基础之网易新闻JSON转模型数组第2天

    IOS开发基础之网易新闻JSON转模型数组第2天 // // HMHeadline.h // 01-网易新闻搭建 // // Created by 鲁军 on 2021/4/11. //#import ...

  2. 使用SwiftyJSON解析JSON

    因为Swift对于类型有非常严格的控制,它在处理JSON时是挺麻烦的,因为它天生就是隐式类型.SwiftyJSON是一个能帮助我们在Swift中使用JSON的开源类库.开始之前,让我们先看一下在Swi ...

  3. YYModel之字典/Json转模型

    从事iOS工作也有两年多了.iOS开发就更久了.说到转模型还是比较喜欢用YYModel框架.当然,期间也用过MJExtension等三方转模型框架. 为什么都喜欢转模型.最开始使用YYModel的时候 ...

  4. Swift JSON与模型转换(HandyJSON封装)

    2018.05.02 20:20:16字数 1,493阅读 5,017 一 简介 二 特性 三 安装使用以及封装 四 使用示例 五 总结 一 简介 HandyJSON是一个用于Swift语言中的JSO ...

  5. Json转模型1--SwiftyJson

    JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上. 但在编程的时候,处理JS ...

  6. Swift JSON转模型Xcode插件

    SwiftJSONModeler是一个Xcode插件,一键转换json字符串为Swfit模型,一键转化 YApi 平台接口为模型,并且自动引入注释. 支持struct, class 支持单json转模 ...

  7. iOS 在线JSON转模型工具(Swift、Objective-C、Java)

    JSON数据自动转模型,帮助有大量模型数据处理的朋友加快开发速度. 链接:https://www.vfun.fun/pages/tools-page/JsonToFile/index.html

  8. 25.SwiftyJSON转换JSON的注意

    在Swift当中, 如果我们需要解析JSON数据的话, 我们需要用上一堆代码才能解析, 而且解析之后还不一定可以正常运行, 这里提供一个第三方的SwiftyJSON, 可以防止我们在解析JSON数据的 ...

  9. JSON转模型归档与解档

    1.用户账户模型类 UserAccount.swift ///用户账户模型 class UserAccount: NSObject, NSCoding{//用户授权的唯一票据,用于调用微博的开放接口, ...

  10. json转换模型利器--JSONExport

    JSONExport 从json 到 Model ,如此的方便 swift oc java 全部支持

最新文章

  1. mac u盘文件过大 拷贝不进去_使用mac时文件太大无法拷贝怎么办
  2. python培训机构推荐-广州有哪些不错的python培训班
  3. LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP
  4. 矩阵分析与多元统计1 线性空间与线性变换1
  5. [机器学习] LightGBM并行计算算子具体实现
  6. OPC服务器如何采集设备的信息,如何将OPC服务器采集的设备数据转为MQTT方式,实现云端发布或订阅...
  7. 面向对象之编写一个完整的类
  8. JAVA 第3课 数组
  9. Spring Data Jpa 审计功能
  10. 有关SQL Server事务日志的十大文章
  11. 流API--流的映射
  12. 部门树_神奇!十堰这个小山村竟然藏着两棵500多年的爱情树!
  13. 【后缀数组】bzoj2217 Secretary
  14. 表情包生成引流源码 - Jason原创
  15. vmplayer linux kernel headers
  16. 使用PS蒙版功能去水印以及Word中的图片合并功能合并公司Logo图片
  17. 堆料堆不出电视头部玩家
  18. 项目是通过文件流的方法查看文件 无法直接在线查看mht后缀文件的解决方案
  19. 数据血缘全方位理解实施指南
  20. 如何写项目方案--从资料准备到书写技巧

热门文章

  1. Tensorflow2.0学习-加载和预处理数据 (七)
  2. 谷歌翻译,一键复活脚本
  3. java.lang.IllegalStateException: Max number of active transactions reached:50
  4. 全球光伏产业战加剧:美国考虑对进口太阳能电池施加紧急关税
  5. 《大数据技术原理与应用》林子雨(第二版)--总结
  6. Teambition产品分析报告
  7. 《Redis开发与运维》笔记-复制
  8. Web漏洞扫描工具AppScan v10.0.0的下载安装与使用
  9. SI9000阻抗计算教程
  10. 13到21年蓝桥杯真题及解析