Codable实现json转Model,是时候干掉HandyJSON了!
自从开始使用Swift做项目,一直都在使用HandyJSON,不可否认,HandyJSON在Swift4.0以前是个好东西,也尝试过其它json转mode的工具,最终发现还是HandyJSON最好用. 去年Swift4.0发布之后,一个最有趣的变化就是Codable协议. 一直都知道Codable来实现json转model,不但效率高,并且简单易用, 但是一直拖到最近才简单封装个小工具,为什么呢? 懒?!!!
在工具的封装上,参考了HandyJSON的部分代码,在使用HandyJSON过程中,一直都觉得designatedPath
是一个很牛逼的存在,开发效率提升了不是一个量级,于是这里也参考HandyJSON中designatedPath的实现代码,并根据Codable的需要改造成fileprivate func getInnerObject(inside jsonData: Data?, by designatedPath: String?) -> Data?
方法. 在这里感谢HandyJSON开发组.
Codable
扩展全部代码如下所示.100余行的代码前后花费一天多的时间. 当了解到google工程师日均一百多行的代码量,我觉得这速度还可以吧. 在代码质量和阅读质量上不敢说有多好,我只是按照自己认为最好的方式来做,如果有哪里不当或者可以用更好方法解决的地方,烦请各位告知,彼此交流学习.
Codable
协议扩展实现代码如下所示:
//
// CodableHelper.swift
// CodableDemo
//
// Created by Walden on 2018/5/7.
// Copyright © 2018年 Walden. All rights reserved.
//import Foundation//扩展Encodable协议,添加编码的方法
public extension Encodable {//1.遵守Codable协议的对象转json字符串public func toJSONString() -> String? {guard let data = try? JSONEncoder().encode(self) else {return nil}return String(data: data, encoding: .utf8)}//2.对象转换成jsonObjectpublic func toJSONObject() -> Any? {guard let data = try? JSONEncoder().encode(self) else {return nil}return try? JSONSerialization.jsonObject(with: data, options: .allowFragments)}
}//扩展Decodable协议,添加解码的方法
public extension Decodable {//3.json字符串转对象&数组public static func decodeJSON(from string: String?, designatedPath: String? = nil) -> Self? {guard let data = string?.data(using: .utf8),let jsonData = getInnerObject(inside: data, by: designatedPath) else {return nil}return try? JSONDecoder().decode(Self.self, from: jsonData)}//4.jsonObject转换对象或者数组public static func decodeJSON(from jsonObject: Any?, designatedPath: String? = nil) -> Self? {guard let jsonObject = jsonObject,JSONSerialization.isValidJSONObject(jsonObject),let data = try? JSONSerialization.data(withJSONObject: jsonObject, options: []),let jsonData = getInnerObject(inside: data, by: designatedPath) else {return nil}return try? JSONDecoder().decode(Self.self, from: jsonData)}
}//扩展Array,添加将jsonString或者jsonObject解码到对应对象数组的方法
public extension Array where Element: Codable {public static func decodeJSON(from jsonString: String?, designatedPath: String? = nil) -> [Element?]? {guard let data = jsonString?.data(using: .utf8),let jsonData = getInnerObject(inside: data, by: designatedPath),let jsonObject = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [Any] else {return nil}return Array.decodeJSON(from: jsonObject)}public static func decodeJSON(from array: [Any]?) -> [Element?]? {return array?.map({ (item) -> Element? inreturn Element.decodeJSON(from: item)})}
}/// 借鉴HandyJSON中方法,根据designatedPath获取object中数据
///
/// - Parameters:
/// - jsonData: json data
/// - designatedPath: 获取json object中指定路径
/// - Returns: 可能是json object
fileprivate func getInnerObject(inside jsonData: Data?, by designatedPath: String?) -> Data? {//保证jsonData不为空,designatedPath有效guard let _jsonData = jsonData,let paths = designatedPath?.components(separatedBy: "."),paths.count > 0 else {return jsonData}//从jsonObject中取出designatedPath指定的jsonObjectlet jsonObject = try? JSONSerialization.jsonObject(with: _jsonData, options: .allowFragments)var result: Any? = jsonObjectvar abort = falsevar next = jsonObject as? [String: Any]paths.forEach({ (seg) inif seg.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) == "" || abort {return}if let _next = next?[seg] {result = _nextnext = _next as? [String: Any]} else {abort = true}})//判断条件保证返回正确结果,保证没有流产,保证jsonObject转换成了Data类型guard abort == false,let resultJsonObject = result,let data = try? JSONSerialization.data(withJSONObject: resultJsonObject, options: []) else {return nil}return data
}
CodableHelper
工具的使用也是非常简单的,代码如下所示:
//首先定义一个结构体Person用来表示数据Model
struct Person: Codable {var name: String?var age: Int?var sex: String?
}//1.jsonString中获取数据封装成Model
let p1String = "{\"name\":\"walden\",\"age\":30,\"sex\":\"man\"}"
let p1 = Person.decodeJSON(from: p1String)//2.jsonString中获取数据封装成Array
let personString = "{\"haha\":[{\"name\":\"walden\",\"age\":30,\"sex\":\"man\"},{\"name\":\"healer\",\"age\":20,\"sex\":\"female\"}]}"
let persons = [Person].decodeJSON(from: personString, designatedPath: "haha")//3.对象转jsonString
let jsonString = p1?.toJSONString()//4.对象转jsonObject
let jsonObject = p1?.toJSONObject()
目前存在问题:
- Model中定义的数据类型和jsonString中数据类型不对应时候会导致解析失败;
- 转载请注明出处
转载于:https://www.cnblogs.com/dev-walden/p/9008866.html
Codable实现json转Model,是时候干掉HandyJSON了!相关推荐
- HandyJSON:Swift语言JSON转Model工具库
背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上. 但在编程的时候,处 ...
- swift 访问oracle,Swift实现JSON转Model - HandyJSON使用讲解
很多时候,我们从服务端请求下的数据都是Json格式,我们需要拿这些数据显示到我们的UI界面. 因此,我们的做法基本都会先将json转为方便使用的数据模型,或者也可以直接转字典解决. 在OC中,我们有很 ...
- Spring控制器响应(action)请求的几种处理方式,如返回JSON,MODEL MODELVIEW,STRING
2019独角兽企业重金招聘Python工程师标准>>> Controller: package **.web.controller;import java.io.IOExceptio ...
- iOS端JSON转Model链式编程框架SuperKVC使用方法与原理
背景 在client编程中.字典转模型是一个极为常见的问题,苹果提供了KVC来实现NSDictionary到Model的注入,可是KVC仅仅能进行单层浅注入.且无法处理类型转换.key与属性名不正确应 ...
- iOS Mac JSON To Model
2019独角兽企业重金招聘Python工程师标准>>> NSString * jsonPath=[[[NSBundle mainBundle] resourcePath] strin ...
- 打开json文件的工具_Flutter中JSON转Model——在线生成
在开发过程中,我们一般都是使用插件或工具一键生成实体类的,这样极大的提高了开发效率,目前我们可以通过在线生成的方式来一键生成Dart类. 1. 使用json_to_dart 地址: https://j ...
- SAP UI5 视图如何使用工程里的 sample data 作为 JSON model 的数据源
在本地工程文件里,新建一个 model 文件夹,里面包含一个 mock.json 文件: 运行时,该文件被加载的路径为 /model/mock.json: 也可以直接写成: createOrdersM ...
- 自定义组件封装之-如何使用SwfityJSON实现JSON/Model相互转换
最近在学习Swift的各种框架,在我的另一篇Swift框架学习之-数据解析SwiftyJSON,已经介绍过了如何使用SwfityJSON这个牛逼的纯Swift写的框架,这里就不作过多介绍,主要来说说我 ...
- Codable 基本使用
Codabel JSON转模 官方文档:Using JSON with Custom Types JSON 介绍:JavaScript Object Notation Codable 是 Swift ...
最新文章
- LINQ技术、EF技术都出来蛮久了,软件开发者、软件公司是否还有必要有自己的代码生成器?...
- [问答题] 考SQL语句的题,题太长了,实在不好回忆了。
- 遇见王沥川的人生感悟_23岁酱油泡饭默默无闻,31岁逆袭人生,王彦霖有何魅力?...
- python的socket模块_python模块:socket模块
- QML工作笔记-在Row布局中如何进行稍许移动(图片Row布局会遇到)
- ubuntu 下groovy 安装配置
- leetcode71 (2022.1.6)
- MTK 驱动---(10) emmc总线
- MySQL数据库---数据库管理
- CSS布局:图片在DIV中上下左右居中(水平和垂直都居中)
- 【迁移学习】PointDAN: A Multi-Scale 3D Domain Adaption Network for Point Cloud Representation
- (附源码)springboot自习室座位预约系统 毕业设计674156
- Pandas数据分析库(2)Python数据分析
- 图像几何校正 (介绍Image to Image几何校正详细步骤)
- 做外贸有没有好的软件?
- 计算机考研2018大纲,2018计算机考研大纲(word版)
- 中国历史上三大盛世的理性审视
- 谷歌翻译 google translation API github开源 实践
- 计算机专业口号 十六个字,计算机学院标语口号,16字计算机与信息学院运动会口号...
- 辣椒app软件测试,辣椒视频(test flight)官方版