使用反射將自定義對(duì)象數(shù)據(jù)序列化成JSON數(shù)據(jù)

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)保留原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,300評(píng)論 6 13
  • # 一度蜜v3.0協(xié)議 --- # 交互協(xié)議 [TOC] ## 協(xié)議說明 ### 請(qǐng)求參數(shù) 下表列出了v3.0版協(xié)...
    c5e350bc5b40閱讀 734評(píng)論 0 0
  • 服務(wù)器采用的是webservice的方式,這種數(shù)據(jù)要請(qǐng)求下來是比較麻煩的,總體思路是把帶有參數(shù)的XML數(shù)據(jù)拼接成字...
    b2e16cc43137閱讀 601評(píng)論 0 0
  • 什么是意志,什么又是痛苦? 意志是為了達(dá)到某種目的而自覺地為之努力的心里狀態(tài)。痛苦是肉體或精神感到非常的難受。 在...
    停不下來的陀螺閱讀 678評(píng)論 0 0

友情鏈接更多精彩內(nèi)容