最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Swift使用反射将自定义对象数据序列化成JSON数据
时间:2022-06-25 23:41:20 编辑:袖梨 来源:一聚教程网
我们知道苹果从IOS5.0后推出了SDK自带的JSON解决方案NSJSONSerialization,这是一个非常好用的JSON生成和解析工具,效率也比其他第三方开源项目高。
但用其生成JSON数据有个限制:只能将Foundation对象转换成JSON。即顶层对象必须是NSArray或者NSDictionary,所有的对象必须是NSString、NSNumber、NSArray、NSDictionary、NSNull的实例。
所以,如果我们想要把自定义类型的数据对象转成JSON数据,NSJSONSerialization就无能为力了。
1,将自定义对象转成JSON数据的实现原理(不借助第三方库)
(1)首先我们使用反射(Reflection)对自定义类型的数据对象中所有的属性进行递归遍历,生成字典类型的数据并返回。
(2)接着使用NSJSONSerialization就可以把这个字典类型的数据转换成jSON数据了。
2,比如我们自定义一个的联系人类
//用户类
class User {
var name:String = "" //姓名
var nickname:String? //昵称
var age:Int? //年龄
var emails:[String]? //邮件地址
var tels:[Telephone]? //电话
}
//电话结构体
struct Telephone {
var title:String //电话标题
var number:String //电话号码
}
3,JSON串生成的功能实现
(1)首先定义一个叫JSON的协议,并对其扩展,实现协议中定义的两个方法。
toJSONModel():将数据转成可用的JSON模型。
toJSONString():将数据转成JSON字符串(其内部会调用前面的toJSONModel()方法)。
(2)将可选类型(Optional),自定义类(User、TeleTelephone),以及基本数据类型进行扩展,使其遵循JSON协议。
同时对于可选类型还要重写toJSONModel()方法,为的是当可选类型值不存在时返回nil,存在时将其转成具体类型并序列化。
//自定义一个JSON协议
protocol JSON {
func toJSONModel() -> AnyObject?
func toJSONString() -> String?
}
//扩展协议方法
extension JSON {
//将数据转成可用的JSON模型
func toJSONModel() -> AnyObject? {
let mirror = Mirror(reflecting: self)
if mirror.children.count > 0 {
var result: [String:AnyObject] = [:]
for case let (label?, value) in mirror.children {
//print("属性:(label) 值:(value)")
if let jsonValue = value as? JSON {
result[label] = jsonValue.toJSONModel()
}
}
return result
}
return self as? AnyObject
}
//将数据转成JSON字符串
func toJSONString() -> String? {
let jsonModel = self.toJSONModel()
//利用OC的json库转换成OC的NSData,
let data : NSData! = try? NSJSONSerialization.dataWithJSONObject(jsonModel!, options: [])
//NSData转换成NSString打印输出
let str = NSString(data:data, encoding: NSUTF8StringEncoding)
return str as String?
}
}
//扩展可选类型,使其遵循JSON协议
extension Optional: JSON {
//可选类型重写toJSONModel()方法
func toJSONModel() -> AnyObject? {
if let x = self {
if let value = x as? JSON {
return value.toJSONModel()
}
}
return nil
}
}
//扩展两个自定义类型,使其遵循JSON协议
extension User: JSON { }
extension Telephone: JSON { }
//扩展Swift的基本数据类型,使其遵循JSON协议
extension String: JSON { }
extension Int: JSON { }
extension Bool: JSON { }
extension Dictionary: JSON { }
extension Array: JSON { }
4,测试样例
//创建一个User实例对象
let user1 = User()
user1.name = "hangge"
user1.age = 100
user1.emails = ["[email protected]","[email protected]"]
//添加动画
let tel1 = Telephone(title: "手机", number: "123456")
let tel2 = Telephone(title: "公司座机", number: "001-0358")
user1.tels = [tel1, tel2]
//输出json字符串
print(user1.toJSONString()!)
看到控制台输出如下信息:
原文:Swift - 使用反射将自定义对象数据序列化成JSON数据
格式化后数据如下:
{
"tels": {
"[1]": {
"number": "001-0358",
"title": "公司座机"
},
"[0]": {
"number": "123456",
"title": "手机"
}
},
"age": 100,
"name": "hangge",
"emails": {
"[1]": "[email protected]",
"[0]": "[email protected]"
}
}
使用第三方库 - JSONKit
1,新建桥街头文件Bridging-Header.h,并设置到编译参数里
1 #include "JSONKit.h"
2,将JSONKit的库文件导入到项目中来(JSONKit.h和JSONKit.m)
3,这时编译会发现报错,这是由于JSONKit库不支持Objective-C的自动引用计数功能导致。
需要在Build Phases -> Compile Sources -> JSONKit.m,双击添加Comipler Flag:-fno-objc-arc 。这样就完成了不支持自动引用计数的配置。
测试代码:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
testJson()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func testJson() {
//Swift 字典对象
let user = [
"uname": "user1",
"tel": ["mobile": "138", "home": "010"]
]
//使用 JSONKit 转换成为 JSON 字符串
let jsonstring = (user as NSDictionary).JSONString()
print(jsonstring);
//由字符串反解析回字典
print(jsonstring.objectFromJSONString() as! NSDictionary)
//使用 JSONKit 转换成为 NSData 类型的 JSON 数据
let jsondata = (user as NSDictionary).JSONData()
print(jsondata);
//由NSData 反解析回为字典
print(jsondata.objectFromJSONData() as! NSDictionary)
}
}
输出结果:
{"uname":"user1","tel":{"home":"010","mobile":"138"}}
{
tel = {
home = 010;
mobile = 138;
};
uname = user1;
}
<7b22756e 616d6522 3a227573 65723122 2c227465 6c223a7b 22686f6d 65223a22 30313022 2c226d6f 62696c65 223a2231 3338227d 7d>
{
tel = {
home = 010;
mobile = 138;
};
uname = user1;
}
相关文章
- 王者荣耀侦探能力大测试攻略 王者荣耀侦探能力大测试怎么过 11-22
- 无期迷途主线前瞻兑换码是什么 11-22
- 原神欧洛伦怎么培养 11-22
- 炉石传说网易云音乐联动怎么玩 11-22
- 永劫无间手游确幸转盘怎么样 11-22
- 无期迷途主线前瞻兑换码是什么 无期迷途主线前瞻直播兑换码介绍 11-22