Json的介紹:21世紀(jì)初,Douglas
Crockford尋找一種簡(jiǎn)便的數(shù)據(jù)交換格式,能夠在服務(wù)器之間交換數(shù)據(jù)。當(dāng)時(shí)通用的數(shù)據(jù)交換語言是XML,但是Douglas
Crockford覺得XML的生成和解析都太麻煩,所以他提出了一種簡(jiǎn)化格式,也就是Json。
Json的規(guī)格非常簡(jiǎn)單,只用一個(gè)頁面幾百個(gè)字就能說清楚,而且Douglas
Crockford聲稱這個(gè)規(guī)格永遠(yuǎn)不必升級(jí),因?yàn)樵撘?guī)定的都規(guī)定了。
(1)并列的數(shù)據(jù)之間用“,”分隔
(2)映射用冒號(hào)“:”表示
(3)并列數(shù)據(jù)的集合(數(shù)組)用“[]”表示
(4)映射的集合(對(duì)象)用大括號(hào)(“{}”)表示
這四條規(guī)則就是json格式的所有內(nèi)容。
列子:
"北京市的面積為16800平方公里,常住人口1600萬人。上海市的面積為6400平方公里,常住人口1800萬。"
寫成json格式就是這樣:
[
{"城市":"北京","面積":16800,"人口":1600},
{"城市":"上海","面積":6400,"人口":1800}
]
如果事先知道數(shù)據(jù)的結(jié)構(gòu),上面的寫法還可以進(jìn)一步簡(jiǎn)化:
[
["北京",16800,1600],
["上海",6400,1800]
]
JSON解析方案a.第三方框架JSONKit\SBJSON\TouchJSON
b.蘋果原生(NSJSONSerialization)
NSJSONSerialization
接下來就正式開始。蘋果官方給出的解析方式是性能最優(yōu)越的,雖然用起來稍顯復(fù)雜。
首先我們?cè)谏厦嬉呀?jīng)有了我希望得到的信息的網(wǎng)站的API給我們的URL,在OC中,我要加載一個(gè)NSURL對(duì)象,來向網(wǎng)站提交一個(gè)Request。到這里需要特別注意了,iOS9的時(shí)代已經(jīng)來臨,我們先前在舊版本中使用的某些類或者方法都已經(jīng)被蘋果官方棄用了。剛剛我們向網(wǎng)站提交了一個(gè)Request,在以往,我們是通過NSURLConnection中的sendSynchronousRequest方法來接受網(wǎng)站返回的Response的,
JSONKit
第三方解析json框架,需要說的有以下幾點(diǎn),
1. JSONKit并沒有系統(tǒng)的快,而且速度相比系統(tǒng)的慢太多了
2.開發(fā)中使用系統(tǒng)的就可以了
這里有一個(gè)小測(cè)試
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event {
// 1. NSURL
NSURL*url = [NSURLURLWithString:@"http://localhost/demo.json"];
// 2.創(chuàng)建請(qǐng)求
NSURLRequest*request = [NSURLRequestrequestWithURL:urlcachePolicy:1timeoutInterval:15];
// 3.發(fā)送異步請(qǐng)求
[NSURLConnectionsendAsynchronousRequest:requestqueue:[NSOperationQueuemainQueue]completionHandler:^(NSURLResponse*_Nullableresponse,NSData*_Nullabledata,NSError*_NullableconnectionError) {
NSLog(@"請(qǐng)求完成")
//記錄開始時(shí)間
CFAbsoluteTimestart =CFAbsoluteTimeGetCurrent();
//使用JSONKit解析json
for(NSIntegeri =0; i <1000*100; i++) {
idresult = [[JSONDecoderdecoder]objectWithData:data];
}
NSLog(@"JSONKit %f",CFAbsoluteTimeGetCurrent() - start);
start =CFAbsoluteTimeGetCurrent();
//使用系統(tǒng)解析json
for(NSIntegeri =0; i <1000*100; i++) {
idresult = [NSJSONSerializationJSONObjectWithData:dataoptions:0error:nil];
}
NSLog(@"系統(tǒng)%f",CFAbsoluteTimeGetCurrent() - start);
}];
}
2016-04-01 15:18:40.706 02-JSONKi[3796:325288]請(qǐng)求完成
2016-04-01 15:18:46.547 02-JSONKi[3796:325288]
JSONKit 5.839473
2016-04-01 15:18:46.799 02-JSONKi[3796:325288]系統(tǒng)0.251958
下面是打印出的時(shí)間,可以看到,在系統(tǒng)方法面前, jsonkit簡(jiǎn)直就被轟成了渣!!
附上一個(gè)簡(jiǎn)單的解析,天氣預(yù)報(bào)
NSURL*url = [NSURLURLWithString:@"http://www.weather.com.cn/data/sk/101280101.html"];
// 2.根據(jù)URL創(chuàng)建一個(gè)請(qǐng)求-不需要緩存
NSURLRequest*request = [NSURLRequestrequestWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:15];
// 3.異步發(fā)送請(qǐng)求
[NSURLConnectionsendAsynchronousRequest:requestqueue:[NSOperationQueuemainQueue]completionHandler:^(NSURLResponse*_Nullableresponse,NSData*_Nullabledata,NSError*_NullableconnectionError) {
//接收到二進(jìn)制數(shù)據(jù),把二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成字典或者數(shù)組
/*
NSJSONReadingMutableContainers= (1UL << 0),容器可變
NSJSONReadingMutableLeaves =(1UL << 1),葉子可變
NSJSONReadingAllowFragments =(1UL << 2)碎片(不是字典也不是數(shù)組)
*/
NSDictionary*result = [NSJSONSerializationJSONObjectWithData:dataoptions:0error:nil][@"weatherinfo"];
NSLog(@"%@",result);
NSLog(@"城市:%@溫度:%@風(fēng)向:%@風(fēng)力:%@相對(duì)濕度:%@",result[@"city"],result[@"temp"],result[@"WD"],result[@"WS"],result[@"SD"]);
json數(shù)據(jù)提交-向服務(wù)器提交數(shù)據(jù)
常規(guī)三步
//1.創(chuàng)建url
NSURL*url=[NSURLURLWithString:@"http://localhost/post/postjson.php"];
//創(chuàng)建請(qǐng)求
NSMutableURLRequest*request=[NSMutableURLRequestrequestWithURL:url];
//設(shè)置POST
[requestsetHTTPMethod:@"POST"];
這里解釋一下post和get的特點(diǎn),因?yàn)榇蠹叶冀?jīng)常要用到
·GET
在請(qǐng)求URL后面以?的形式跟上發(fā)給服務(wù)器的參數(shù),參數(shù)以"參數(shù)名"="參數(shù)值"的形式拼接,多個(gè)參數(shù)之間用&分隔;
GET的本質(zhì)是從服務(wù)器得到數(shù)據(jù),效率更高.并且GET請(qǐng)求可以被緩存.
注意:GET的長(zhǎng)度是有限制的,不同的瀏覽器有不同的長(zhǎng)度限制,一般在2~8K之間;
·POST
POST的本質(zhì)是向服務(wù)器發(fā)送數(shù)據(jù),也可以獲得服務(wù)器處理之后的結(jié)果,效率不如GET.POST請(qǐng)求不可以被緩存,每次刷新之后都需要重新提交表單.
發(fā)送給服務(wù)器的參數(shù)全部放在'請(qǐng)求體'中;
理論上,POST傳遞的數(shù)據(jù)量沒有限制.
注意:所有涉及到用戶隱私的數(shù)據(jù)(密碼/銀行卡號(hào)等...)都要用POST的方式傳遞.
// 2.2設(shè)置請(qǐng)求體(這里用了數(shù)組的模式,發(fā)送多個(gè)json文件)
NSDictionary*params =@{
@"username":@"zhangsan",
@"password":@123456
};
NSDictionary*params1 =@{
@"username":@"zhangsan",
@"password":@123456
};
NSArray*jsonArray =@[params, params1];
注意json一定要格式正確,為了更好的確定上傳數(shù)據(jù)是不是json類型,我們可以在代碼中檢查一下
//驗(yàn)證對(duì)象是否符合json格式
if(![NSJSONSerializationisValidJSONObject:jsonArray]) {
NSLog(@"對(duì)象不符合json要求");
return;
}
這樣,當(dāng)格式有問題時(shí)候就會(huì)自動(dòng)提示,格式有問題了
//把字典/數(shù)組轉(zhuǎn)成一個(gè)二進(jìn)制數(shù)據(jù)
NSData*jsonData = [NSJSONSerializationdataWithJSONObject:jsonArrayoptions:0error:nil];
post的請(qǐng)求體
[requestsetHTTPBody:jsonData]
接下來就是發(fā)送json了
// 3.發(fā)送請(qǐng)求
[NSURLConnectionsendAsynchronousRequest:requestqueue:[NSOperationQueuemainQueue]completionHandler:^(NSURLResponse*_Nullableresponse,NSData*_Nullabledata,NSError*_NullableconnectionError) {
//把返回的二進(jìn)制數(shù)據(jù)轉(zhuǎn)成字符串
NSString*result = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
//檢驗(yàn)一下文件的類型
NSLog(@"%@",result);
}];
}
接下來是打印結(jié)果了
2016-04-01 13:31:47.601 05-向服務(wù)器提交JSON數(shù)據(jù)[2775:207528]
[{"username":"zhangsan","password":123456},{"username":"zhangsan","password":123456}]從服務(wù)器返回
(轉(zhuǎn)載自微信)