NSJSONSerialization,這是一個(gè)非常好用的JSON生成和解析工具,效率也比其他第三方開源項(xiàng)目高。
但用其生成JSON數(shù)據(jù)有個(gè)限制:只能將Foundation對(duì)象轉(zhuǎn)換成JSON。即頂層對(duì)象必須是NSArray或者NSDictionary,所有的對(duì)象必須是NSString、NSNumber、NSArray、NSDictionary、NSNull的實(shí)例。
所以,如果我們想要把自定義類型的數(shù)據(jù)對(duì)象轉(zhuǎn)成JSON數(shù)據(jù),NSJSONSerialization就無能為力了。
1,將自定義對(duì)象轉(zhuǎn)成JSON數(shù)據(jù)的實(shí)現(xiàn)原理(不借助第三方庫)
(1)首先我們使用反射(Reflection)對(duì)自定義類型的數(shù)據(jù)對(duì)象中所有的屬性進(jìn)行遞歸遍歷,生成字典類型的數(shù)據(jù)并返回。
(2)接著使用NSJSONSerialization就可以把這個(gè)字典類型的數(shù)據(jù)轉(zhuǎn)換成jSON數(shù)據(jù)了。
2,比如我們自定義一個(gè)的聯(lián)系人類
//用戶類
classUser{
varname:String=""http://姓名
varnickname:String?//昵稱
varage:Int?//年齡
varemails:[String]?//郵件地址
vartels:[Telephone]?//電話
}
//電話結(jié)構(gòu)體
structTelephone{
vartitle:String//電話標(biāo)題
varnumber:String//電話號(hào)碼
}
3,JSON串生成的功能實(shí)現(xiàn)
(1)首先定義一個(gè)叫JSON的協(xié)議,并對(duì)其擴(kuò)展,實(shí)現(xiàn)協(xié)議中定義的兩個(gè)方法。
toJSONModel():將數(shù)據(jù)轉(zhuǎn)成可用的JSON模型。
toJSONString():將數(shù)據(jù)轉(zhuǎn)成JSON字符串(其內(nèi)部會(huì)調(diào)用前面的toJSONModel()方法)。
(2)將可選類型(Optional),自定義類(User、TeleTelephone),以及基本數(shù)據(jù)類型進(jìn)行擴(kuò)展,使其遵循JSON協(xié)議。
同時(shí)對(duì)于可選類型還要重寫toJSONModel()方法,為的是當(dāng)可選類型值不存在時(shí)返回nil,存在時(shí)將其轉(zhuǎn)成具體類型并序列化
//自定義一個(gè)JSON協(xié)議
protocolJSON{
functoJSONModel() ->AnyObject?
functoJSONString() ->String?
}
//擴(kuò)展協(xié)議方法
extensionJSON{
//將數(shù)據(jù)轉(zhuǎn)成可用的JSON模型
functoJSONModel() ->AnyObject? {
letmirror =Mirror(reflecting:self)
ifmirror.children.count > 0? {
varresult: [String:AnyObject] = [:]
forcaselet(label?, value)inmirror.children {
//print("屬性:\(label)???? 值:\(value)")
ifletjsonValue = valueas?JSON{
result[label] = jsonValue.toJSONModel()
}
}
returnresult
}
returnselfas?AnyObject
}
//將數(shù)據(jù)轉(zhuǎn)成JSON字符串
functoJSONString() ->String? {
letjsonModel =self.toJSONModel()
//利用OC的json庫轉(zhuǎn)換成OC的NSData,
letdata :NSData! = try?NSJSONSerialization.dataWithJSONObject(jsonModel!, options: [])
//NSData轉(zhuǎn)換成NSString打印輸出
letstr =NSString(data:data, encoding:NSUTF8StringEncoding)
returnstrasString?
}
}
//擴(kuò)展可選類型,使其遵循JSON協(xié)議
extensionOptional:JSON{
//可選類型重寫toJSONModel()方法
functoJSONModel() ->AnyObject? {
ifletx =self{
ifletvalue = xas?JSON{
returnvalue.toJSONModel()
}
}
returnnil
}
}
//擴(kuò)展兩個(gè)自定義類型,使其遵循JSON協(xié)議
extensionUser:JSON{ }
extensionTelephone:JSON{ }
//擴(kuò)展Swift的基本數(shù)據(jù)類型,使其遵循JSON協(xié)議
extensionString:JSON{ }
extensionInt:JSON{ }
extensionBool:JSON{ }
extensionDictionary:JSON{ }
extensionArray:JSON{ }
4,測(cè)試樣例
//創(chuàng)建一個(gè)User實(shí)例對(duì)象
letuser1 =User()
user1.name ="hangge"
user1.age = 100
user1.emails = ["hangge@hangge.com","system@hangge.com"]
//添加動(dòng)畫
lettel1 =Telephone(title:"手機(jī)", number:"123456")
lettel2 =Telephone(title:"公司座機(jī)", number:"001-0358")
user1.tels = [tel1, tel2]
//輸出json字符串
print(user1.toJSONString()!)
看到控制臺(tái)輸出如下信息:

格式化后數(shù)據(jù)如下:
{
"tels": {
"[1]": {
"number": "001-0358",
"title": "公司座機(jī)"
},
"[0]": {
"number": "123456",
"title": "手機(jī)"
}
},
"age": 100,
"name": "hangge",
"emails": {
"[1]": "system@hangge.com",
"[0]": "hangge@hangge.com"
}
}
原文出自:www.hangge.com轉(zhuǎn)載請(qǐng)保留原文