JSON (JavaScript Object Notation JS對(duì)象標(biāo)記) 是一種輕量級(jí)的數(shù)據(jù)交換格式. 它采用完全獨(dú)立于編程語(yǔ)言的文本格式來(lái)存儲(chǔ)和表示數(shù)據(jù).
JSON 和 JS 的關(guān)系
JSON 是JS對(duì)象的字符串表示法,它使用文本表示一個(gè)JS對(duì)象的信息.JSON本質(zhì)上是一個(gè)具有特定格式字符串, 在JS語(yǔ)言中使用JSON.stringify()方法把對(duì)象轉(zhuǎn)換為JSON字符串(就是字符串!). 事實(shí)上, JSON作為一種完全獨(dú)立于語(yǔ)言的數(shù)據(jù)交換格式 廣泛用于許多場(chǎng)合, 許多語(yǔ)言都有對(duì)應(yīng)的JSON數(shù)據(jù)格式的解析框架.為什么是JSON!
無(wú)論是移動(dòng)端APP還是Web端(這里統(tǒng)稱為"前端"),都需要和后臺(tái)進(jìn)行數(shù)據(jù)交換.
假設(shè)一個(gè)登陸場(chǎng)景:我們需要把用戶名和密碼通過(guò)網(wǎng)絡(luò)請(qǐng)求發(fā)送給后臺(tái),后臺(tái)返回我們一個(gè)token.
事實(shí)上我們和后臺(tái)進(jìn)行交換的數(shù)據(jù)要比這復(fù)雜,這里首先定義一個(gè)ModelObject類存放我們需要向后臺(tái)發(fā)送的數(shù)據(jù).
class ModelObject{
let name:String?
let password:String?
//我們實(shí)際開(kāi)發(fā)中用到的模型要比這復(fù)雜,這里簡(jiǎn)單化
init(name:String, password:Stirng){
self.name = name
self.password = password
}
init()
{
name = nil
password = nil
}
}
假設(shè)你是移動(dòng)APP端的開(kāi)發(fā)者, 既然是一種數(shù)據(jù)數(shù)據(jù)交換格式,那肯定是前端與后端之間的數(shù)據(jù)交換. 你獲取用戶輸入的name 和 passWord 并初始化得到一個(gè)ModelObject對(duì)象. 現(xiàn)在你需要把這個(gè)對(duì)象發(fā)送到后臺(tái)去.
怎么做?
直接發(fā)送行不行? 要知道我們的數(shù)據(jù)都是以二進(jìn)制的形式存儲(chǔ)在內(nèi)存或者磁盤上的(這是數(shù)據(jù)的物理表現(xiàn)形式), 數(shù)據(jù)可能有不同的邏輯表現(xiàn)形式(我們定義不同的類就是從邏輯形式上定義數(shù)據(jù),但本質(zhì)上它的物理表現(xiàn)形式是不會(huì)變的), 010101010的電信號(hào)... 也就是二進(jìn)制流. 暫且這么理解.
理論上,如果你直接發(fā)送一個(gè)ModelObject對(duì)象的二進(jìn)制也是可以的.前提是后臺(tái)拿到這個(gè)二進(jìn)制的ModelObject對(duì)象,讀取并無(wú)誤的轉(zhuǎn)換成自己所在環(huán)境的一個(gè)所需要的對(duì)象, 如果哪天前后端統(tǒng)一了所有的語(yǔ)言, 或者有一個(gè)所有語(yǔ)言都支持的統(tǒng)一的框架,可以自動(dòng)識(shí)別不同語(yǔ)言的二進(jìn)制對(duì)象,并且轉(zhuǎn)換成在該語(yǔ)言環(huán)境下的對(duì)象.
目前我們應(yīng)該怎么做?
我們應(yīng)該首先把ModelObject對(duì)象轉(zhuǎn)換成一個(gè)字典,然后通過(guò)方法把字典轉(zhuǎn)換成JSONData.
- 為什么需要轉(zhuǎn)成字典呢? 因?yàn)镺bjective-C或者Swift中沒(méi)有前面提到的那種直接把對(duì)象轉(zhuǎn)換成對(duì)應(yīng)的JSON字符串的方法.而JSON在Objective-C中恰恰對(duì)應(yīng)Foundation中的dictionary.
- 為什么要把字典轉(zhuǎn)換成JSONData? 因?yàn)榫W(wǎng)絡(luò)上傳輸數(shù)據(jù)只能通過(guò)二進(jìn)制流的方式進(jìn)行傳遞. 這里要注意統(tǒng)一編碼.不過(guò)這里傳遞的是字符流,字符是通過(guò)二進(jìn)制來(lái)表示的.
但是這里的二進(jìn)制字符流是由特定格式的,是一種叫做JSON的數(shù)據(jù)交換格式.
后臺(tái)
由于我沒(méi)有做過(guò)后臺(tái),具體的處理流程不清楚. 不過(guò)我猜測(cè) ,也是響應(yīng)了請(qǐng)求,拿到了請(qǐng)求中的二進(jìn)制數(shù)據(jù), 然后根據(jù)JSON的規(guī)則解析,來(lái)還原對(duì)象的值.
最后Objective-C中的JSON的解析:
在Objective-C中使用NSJSONSerialization在JSONObject(事實(shí)上就是Foundation對(duì)象)和JSONDate(JSON格式的字符串<以二進(jìn)制形式存在,這也是我們網(wǎng)絡(luò)請(qǐng)求后直接得到的東西>)之間進(jìn)行轉(zhuǎn)換.
這里只是簡(jiǎn)單的使用方法舉例,具體說(shuō)明請(qǐng)參考NSJSONSerialization
- Creating a JSON Object:
- JSONObjectWithData:options:error:
Returns a Foundation object from given JSON data.
Declaration
- (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError * _Nullable *)error;
Parameters
data
A data object containing JSON data.
opt
Options for reading the JSON data and creating the Foundation objects.
For possible values, see NSJSONReadingOptions.
error
If an error occurs, upon return contains an NSError object with code NSPropertyListReadCorruptError that describes the problem.
Return Value
A Foundation object from the JSON data in data, or nil if an error occurs.
反序列化:將從服務(wù)器接收到的二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成 NSDictionary / NSArray 的過(guò)程,簡(jiǎn)化程序開(kāi)發(fā),便于后續(xù)的字典轉(zhuǎn)模型
//NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *resultDic1 = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
//得到一個(gè)Foundation對(duì)象,便于接下來(lái)轉(zhuǎn)成響應(yīng)的模型.
- Creating JSON Data
- dataWithJSONObject:options:error:
Returns JSON data from a Foundation object.
Declaration
- (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError * _Nullable *)error;
Parameters
obj
The object from which to generate JSON data. Must not be nil.
opt
Options for creating the JSON data.
See NSJSONWritingOptions for possible values.
error
If an internal error occurs, upon return contains an NSError object with code NSPropertyListWriteInvalidError that describes the problem.
Return Value
JSON data for obj, or nil if an internal error occurs. The resulting data is encoded in UTF-8.
序列化:
將字典或者數(shù)組發(fā)送給服務(wù)器之前,轉(zhuǎn)換成二進(jìn)制數(shù)據(jù),方便網(wǎng)絡(luò)傳輸。
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonObj options:NSJSONWritingPrettyPrinted error:&error];
//NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
目前還在學(xué)習(xí)的道路上...
參考: