NSJSONSerialization批糟,這是一個(gè)非常好用的JSON生成和解析工具谣蠢,效率也比其他第三方開(kāi)源項(xiàng)目高。
但用其生成JSON數(shù)據(jù)有個(gè)限制:只能將Foundation對(duì)象轉(zhuǎn)換成JSON。即頂層對(duì)象必須是NSArray或者NSDictionary,所有的對(duì)象必須是NSString瘤礁、NSNumber、NSArray辖源、NSDictionary、NSNull的實(shí)例希太。
所以克饶,如果我們想要把自定義類(lèi)型的數(shù)據(jù)對(duì)象轉(zhuǎn)成JSON數(shù)據(jù),NSJSONSerialization就無(wú)能為力了誊辉。
1矾湃,將自定義對(duì)象轉(zhuǎn)成JSON數(shù)據(jù)的實(shí)現(xiàn)原理(不借助第三方庫(kù))
(1)首先我們使用反射(Reflection)對(duì)自定義類(lèi)型的數(shù)據(jù)對(duì)象中所有的屬性進(jìn)行遞歸遍歷,生成字典類(lèi)型的數(shù)據(jù)并返回堕澄。
(2)接著使用NSJSONSerialization就可以把這個(gè)字典類(lèi)型的數(shù)據(jù)轉(zhuǎn)換成jSON數(shù)據(jù)了邀跃。
2霉咨,比如我們自定義一個(gè)的聯(lián)系人類(lèi)
//用戶類(lèi)
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)將可選類(lèi)型(Optional),自定義類(lèi)(User蒜茴、TeleTelephone)星爪,以及基本數(shù)據(jù)類(lèi)型進(jìn)行擴(kuò)展,使其遵循JSON協(xié)議粉私。
同時(shí)對(duì)于可選類(lèi)型還要重寫(xiě)toJSONModel()方法顽腾,為的是當(dāng)可選類(lèi)型值不存在時(shí)返回nil,存在時(shí)將其轉(zhuǎn)成具體類(lèi)型并序列化
//自定義一個(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庫(kù)轉(zhuǎn)換成OC的NSData诺核,
letdata :NSData! = try?NSJSONSerialization.dataWithJSONObject(jsonModel!, options: [])
//NSData轉(zhuǎn)換成NSString打印輸出
letstr =NSString(data:data, encoding:NSUTF8StringEncoding)
returnstrasString?
}
}
//擴(kuò)展可選類(lèi)型抄肖,使其遵循JSON協(xié)議
extensionOptional:JSON{
//可選類(lèi)型重寫(xiě)toJSONModel()方法
functoJSONModel() ->AnyObject? {
ifletx =self{
ifletvalue = xas?JSON{
returnvalue.toJSONModel()
}
}
returnnil
}
}
//擴(kuò)展兩個(gè)自定義類(lèi)型,使其遵循JSON協(xié)議
extensionUser:JSON{ }
extensionTelephone:JSON{ }
//擴(kuò)展Swift的基本數(shù)據(jù)類(lèi)型猪瞬,使其遵循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)畫(huà)
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)保留原文