Swift json字典转模型 项目记录
背景
最近项目开始转用Swift3开发,由于Swift中json(字典)转模型的选择方案较多,笔者最开始选择了HandyJSON的方案,在使用一段时间后发现当要进行某个字段取值使用时需要进行各种的转化判断,比较麻烦(但是安全、保证程序不会抛出异常)。于是笔者引入了SwiftyJSON库。于是取值变得简单方便。
新问题
由于SwiftyJSON的引入,笔者将网络请求基本请求完成后进行了JSON化处理,如果后面再进行HandyJSON转模型处理,就要进行二次操作,感觉效率上会有影响。
当然也可以选择网络请求基类对返回数据不做任何处理,交还由各个请求发起者处理,但这样会导致大量的重复代码。在这种情况下笔者思考利用JSON自己进行模型转化。
方案
runtime机制给模型赋值
在OC中我们的json转模型通常是利用runtime机制获取模型对象的属性列表,再进行判断并取值赋值.由于Swift中已经逐渐放弃runtime机制。因此笔者放弃了此种方案
反射机制给模型赋值
在Swift中有一个Mirror类,具备获取对象信息能力、能获取对象名字及值。接着再通过kvc的方式将值写入模型即可。(HandyJSON的值写入是直接通过内存地址写入)
实现
这里笔者通过反射机制来实现json转模型(由于项目中使用到了SwiftyJSON,因此添加了JOSN转化为模型方法)。模型基类代码如下
import UIKit
import SwiftyJSON
class BQModel: NSObject {
required override init() {
}
required init(_ dic: Dictionary<String,Any>) {
super.init()
self.configValue(dic)
}
func configValue(_ dic: Dictionary<String,Any>) {
let mirror = Mirror(reflecting: self)
for p in mirror.children {
let name = p.label!
if let value = dic[name] {
if p.value is BQModel && value is Dictionary<String, Any> {
(p.value as! BQModel).configValue(value as! Dictionary<String, Any>)
}else {
self.setValue(value, forKey: name)
}
}
}
}
override var description: String {
let mirror = Mirror(reflecting: self)
var result = [String:Any]()
for p in mirror.children {
let name = p.label!
result[name] = p.value
}
return String(describing: "<\(self.classForCoder):\(Unmanaged.passRetained(self).toOpaque())>\n\(result)")
}
// MARK:- ***** if has SWIFTJSON can use this Mesthod *****
required init(_ json: JSON) {
super.init()
self.configValue(json)
}
func configValue(_ json: JSON) {
if let modelInfo = json.dictionary {
let mirror = Mirror(reflecting: self)
for p in mirror.children {
let name = p.label!
if let value = modelInfo[name] {
switch value.type {
case .string:
self.setValue(value.string, forKey: name)
case .number:
self.setValue(value.number, forKey: name)
case .bool:
self.setValue(value.bool, forKey: name)
case .dictionary:
let val = self.value(forKey: name)
if val is BQModel {
(val as! BQModel).configValue(value)
}else {
self.setValue(value.dictionary, forKey: name)
}
case .array:
self.setValue(value.array, forKey: name)
default:
break
}
}
}
}
}
}
extension Array where Element: BQModel {
static func modelArr(arr: Array<Dictionary<String,Any>>) -> Array<Element> {
var result = [Element]()
for dic in arr {
result.append(Element(dic))
}
return result
}
//MARK:- ***** if has SWIFTJSON can use this Mesthod *****
static func modelArr(arr: Array<JSON>) -> Array<Element> {
var result = [Element]()
for json in arr {
result.append(Element(json))
}
return result
}
}
测试
当模型写好后,笔者进行了一个简单的测试。将一万个对象的json字符串作为网络请求返回值,模拟网络请求。
然后分别用HandyJSON和BQModel来进行模型转化
模型代码,保证属性相同
class Person: BQModel {
var name: String?
var age: Int = 0
var std = Student()
}
class Student: BQModel {
var id: String?
var num: Int = 0
var isOld: Bool = false
}
struct ABC: HandyJSON {
var name: String?
var age: Int = 0
var std = ABD()
}
struct ABD: HandyJSON {
var id: String?
var num: Int = 0
var isOld: Bool = false
}
测试代码
//模拟网络请求返回数据JSON化处理
let json = JSON(["name":"asd","age":11,"std":["id":"123","num":12]])
//数据处理
let arrJSON = [JSON](repeating: json, count: 10000)
let arrDict = [Dictionary](repeating: ["name":"asd","age":11,"std":["id":"123","num":12]], count: 10000)
let string = BQTool.jsonFromObject(obj: arrDict)
//时间测试
print("BQModel with JSON")
self.getTime {
let _ = [Person].modelArr(arr: arrJSON)
}
print("BQModel with Dict")
self.getTime {
et data = string.data(using: .utf8)!
let obj = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as! Array<Dictionary<String,Any>>
let _ = [Person].modelArr(arr: obj)
}
print("HandyJSON")
self.getTime {
let _ = [ABC].deserialize(from: string)
}
测试结果及分析
进行三次测试结果数据如下
有测试数据得出BQModel的效率在这里比HandyJSON较好。需要注意的是笔者缩写的模型考虑情况肯定没有HandyJSON多。所以在通用性方面应该没有HandyJSON做的好(这里也可能是HandyJSON效率比BQModel低的原因)。另外HandyJSON采用内存地址写入,而笔者采用KVC写入,并不完全符合Swift的特性。所以在采用哪种模型方案的时候还是看大家的需求和选择。最后附上笔者Swift工具库连接,有兴趣的朋友可以去看看。如果上述有什么错误请指正,谢谢!
Swift json字典转模型 项目记录的更多相关文章
- iOS彩票项目--第七天,初次读取json数据、KVC转模型技巧、运行时字典转模型以及初步对显示网页的操作并且跟踪标签
一.初次读取json数据 二.KVC转模型技巧,这里的技巧主要解决的是字典中的key 与 模型中有的属性对应不起来的时候 的解决办法 <方法1> <方法2>运行时字典转模型,运 ...
- iOS/macOS推荐个高效苹果开发工具, JSON 转模型代码工具,不再为复杂JSON数据写模型而烦恼,支持Swift/Objective-C,极速转换
CCJSON 是一款运行在macOS上 JSON 转模型代码工具,不再为复杂JSON数据写模型而烦恼,可识别嵌套模型,字典/数组,支持Swift/Objective-C,操作方便,极速转换.下载 效果 ...
- iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)
一.JSON 1.JSON简介什么是JSONJSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典 ...
- swift 利用 Reflect(字典转模型)
1. 导入Reflect(字典转模型)框架 2. 让它继承Reflect这个类,如下代码所示: class IWUser: Reflect { /** * 用户的ID */ var idstr:N ...
- iOS字典转模型MJExtension使用
如果项目是纯OC的建议使用,MJExtension是一套字典和模型之间互相转换的超轻量级框架,可以轻松完成: 字典(JSON) --> 模型(Model) 模型(Model) --> 字典 ...
- 利用Runtime实现简单的字典转模型
前言 我们都知道,开发中会有这么一个过程,就是将服务器返回的数据转换成我们自己定义的模型对象.当然服务器返回的数据结构有xml类型的,也有json类型的.本文只讨论json格式的. 大家在项目中一般是 ...
- ios开发网络学习二:URL转码以及字典转模型框架MJExtension的使用
一:url转码,当url中涉及到中文的时候,要考虑转码,用UTF8对中文的url进行转码 #import "ViewController.h" @interface ViewCon ...
- IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型
*************application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...
- 字典转模型框架 Mantle的使用:国外程序员最常用的iOS模型
Mantle简介 Mantle 是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary) ...
随机推荐
- unity 本地帮助文档 慢
unity ,打开本地帮助文档时,有时会加载很慢,主要原因是网页里嵌入了访问google的代码.解决办法:打开本地hosts文件,里面加入"127.0.0.1 fonts.googleapi ...
- css写出三角形(兼容IE)
css写出三角形 利用css写三角形,兼容IE7 .arrow-up { width:0px; height:0px; border-left:10px solid transparent; bo ...
- 玩玩kafka1 单机安装
今天主要来一遍kafka单机版的安装,比较简单易上手,关于kafka的介绍我就不贴了,大家可以自行搜索 1.首先将tgz包传到centos目录下(这里使用xftp工具) ok后查看一下tgz包是否已经 ...
- [转]亿级Web系统搭建:单机到分布式集群
当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...
- 高性能网站架构设计之缓存篇(1)- Redis C#客户端
一.什么 RedisREmote DIctionary Server,简称 Redis,是一个类似于Memcached的Key-Value存储系统.相比Memcached,它支持更丰富的数据结构,包括 ...
- PHP 底层的运行机制与原理 --转
发现一片总结的还不错的文章,记录一下 PHP说简单,但是要精通也不是一件简单的事.我们除了会使用之外,还得知道它底层的工作原理. PHP是一种适用于web开发的动态语言.具体点说,就是一个用C语言实现 ...
- SparkMLib分类算法之朴素贝叶斯分类
SparkMLib分类算法之朴素贝叶斯分类 (一)朴素贝叶斯分类理解 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法.简单来说,朴素贝叶斯分类器假设样本每个特征与其他特征都不相关.举个例子, ...
- .NET 通过 Autofac 和 DynamicProxy 实现AOP
什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.实现AOP主要由两 ...
- 【http】http的方法,状态码和组成部分
Http(Hypertext Transfer Protocol) HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传 ...
- php中for循环的应用
for 循环是 PHP 中最复杂的循环结构.它的行为和 C 语言的相似.在PHP中使用的是执行相同的代码集的次数. for 循环的语法是: for (expr1; expr2; expr3)state ...