iOS網(wǎng)絡交互數(shù)據(jù)格式解析之json
JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,目前在網(wǎng)絡交互過程中有著舉足輕重的地位如果您對json還有什么不清楚的話建議去看json百度百科。
在iOS平臺上,Apple 從 iOS 5.0 才開始提供原生的json生成和解析的API,使用起來 非常方便,但這樣就無法為iOS 5.0 之前版本的用戶服務了。對于iOS 5.0以前的系統(tǒng),json的使用得益于無數(shù)無私的開源擁護者的貢獻。估計大多數(shù)開發(fā)者現(xiàn)在還不會直接拋棄仍在使用 5.0 以前版本的用戶,所以這里優(yōu)先介紹3種主要的開源庫的使用,然后再介紹新的原生API的使用。
測試數(shù)據(jù)我們使用國家氣象局提供的天氣預報接口:
- http://m.weather.com.cn/data/101010100.html
- http://www.weather.com.cn/data/cityinfo/101010100.html
- http://www.weather.com.cn/data/sk/101010100.html
您可以用瀏覽器打開,看看這三個地址到底是什么--其實你可以分別看到3個字符串,沒錯,你才對了,這就是我們測試用的 json 數(shù)據(jù)。
我們打開 github 搜索關(guān)鍵字 json ,程序語言選擇 Objective-C ;可以得到 n 頁結(jié)果。我們就依次介紹最前面的3個:stig/json-framework、TouchCode/TouchJSON、johnezang/JSONKit。緊接著介紹 iOS 5.0 開始提供的原生 JSON 處理類。
此處我們將這三個開源庫及原生JSON處理類放到一個工程里介紹了,但開源庫 stig/json-framework 編譯是需要ARC支持的,而TouchCode/TouchJSON 和 johnezang/JSONKit 是不需要 ARC 支持。這樣我么在工程中就需要打開 ARC (可以在創(chuàng)建工程的時候就選中 ARC,也可和下圖一樣在build setting 中設(shè)置兩處 為 YES)
然后對后兩者在編譯規(guī)則中做簡單的處理,-fno-objc-arc即是規(guī)定該文件編譯時不需要ARC支持,如下圖:
因為我們測試的數(shù)據(jù)來自于互聯(lián)網(wǎng),所以我們需要網(wǎng)絡支持,這里我們需要添加系統(tǒng)庫:CFNetwork.framework,如下圖
終于開始寫代碼了,公用代碼:
1.將url地址定義成字符串常量
2.import 相應文件;
3.連接到測試的url;
4.取得json數(shù)據(jù),并將其以字符串的形式顯示在第一個 TextView 上;
5.將解析后的JSON實際內(nèi)容顯示在第二個 TextView 上
- //為了方便,先在工程中的 .pch 文件中定義 字符串常量
- #define jsonSourceURLAddress_1 @"http://m.weather.com.cn/data/101010100.html"
- #define jsonSourceURLAddress_2 @"http://www.weather.com.cn/data/sk/101010100.html"
- #define jsonSourceURLAddress_3 @"http://www.weather.com.cn/data/cityinfo/101010100.html
- #import "LTRootViewController.h"
- //測試工程中 3 中方式都是在這個controller中使用,將需要的import進來
- #import "SBJson.h"
- #import "TouchJSON/JSON/CJSONDeserializer.h"
- #import "JSONKit/JSONKit.h"
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- //向開源的地址發(fā)送連接請求
- //這里使用的是異步的請求
- NSURL *url = [NSURL URLWithString:jsonSourceURLAddress_1];
- NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];
- NSURLConnection *urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
- [urlConnection start];
- }
- #pragma mark - NSURLConnectionDataDelegate methods
- - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- {
- UIAlertView * alertV = [[UIAlertView alloc] initWithTitle:@"網(wǎng)絡連接失敗" message:[NSString stringWithFormat:@"%@",error] delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
- [alertV show];
- }
- - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- {
- //這里我們終于拿到了網(wǎng)絡返回的 JSON 數(shù)據(jù) data
- self.m_JsonData = data;
- self.m_sourceJsonTV.text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- }
- - (void)displayWithParsedDic:(NSDictionary *)rootDic
- {
- //rootDic 來自與我們所用的各種方式將 JSON 解析后得到的字典
- //下面用于在 TextView 中顯示解析成功的JSON實際內(nèi)容
- if (!rootDic) {
- self.m_parsedJsonTV.text = @"cleaned...";
- }else{
- NSDictionary *weatherInfo = [rootDic objectForKey:@"weatherinfo"];
- //由于字典中內(nèi)容太多,我們只顯示了一部分,諸如 temp2,temp3,...我們木有在這一一顯示
- self.m_parsedJsonTV.text = [NSString stringWithFormat:@"今天是 %@ %@ %@ 的天氣狀況是:%@ %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];
- }
- }
現(xiàn)在分類的介紹這4種JSON解析方式:
1、json-framework
也有人管這庫叫SBJson我們從 github 上下載 json-framework這個庫并將其導入到我們的工程中(僅需將下載下來的文件夾中,classes 目錄下的所有文件復制導入到我們的工程就行)。在任何你需要使用json處 :#import "SBJson.h"
- - (IBAction)sbjsonAction:(id)sender {
- //此處是使用 json-framework (SBJSON)解析,得到解析后存入字典:rootDic,并顯示
- SBJsonParser * parser = [[SBJsonParser alloc] init];
- NSString * jsonStr = [[NSString alloc] initWithData:self.m_JsonData encoding:NSUTF8StringEncoding];
- NSDictionary *rootDic = [parser objectWithString:jsonStr];
- [self displayWithParsedDic:rootDic];
- }
2、TouchJSON
我糾結(jié)了很久,要不要介紹這個庫了,因為作者在github上聲稱:"But you should NOT be using this code in your new projects"。
我們從 github 上下載 TouchCode/TouchJSON 這個庫并將其導入到我們的工程中(僅需將下載下來的文件夾中,Source 目錄下的所有文件復制導入到我們的工程)。但是 Source/Experimental目錄下提供的功能慎用( Be aware that the code in the Experimental subdirectory of Source is just that and may not have been extensively tested and/or have extra dependencies)。在任何你需要使用json處:#import "CJSONDeserializer.h"
- - (IBAction)touchJsonAction:(id)sender {
- //此處是使用 TouchJSON 解析,得到解析后存入字典:rootDic,并顯示
- NSError * error = nil;//error 用來存儲解析過程中可能出現(xiàn)的錯誤信息
- NSDictionary *rootDic = [[CJSONDeserializer deserializer] deserialize:self.m_JsonData error:&error];
- [self displayWithParsedDic:rootDic];
- }
3、JSONKit
我們從 github 上下載 johnezang/JSONKit 這個庫并將其導入到我們的工程中(這個很簡單,代碼文件只有2個,都復制導入我們的工程吧)。
- - (IBAction)jsonkitAction:(id)sender {
- //此處是使用 JSONKit 解析,得到解析后存入字典:rootDic,并顯示
- NSDictionary * rootDic = [self.m_JsonData objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode];
- [self displayWithParsedDic:rootDic];
- }
4、原生JSON處理類
使用原生的JSON處理類解析就相當方便了,據(jù)說也是最快的(未親測速度):
- - (IBAction)nsjsonAction:(id)sender {
- //此處是使用原生的 JSON 處理類解析,得到解析后存入字典:rootDic,并顯示
- NSError *error = nil;
- NSDictionary * rootDic = [NSJSONSerialization JSONObjectWithData:self.m_JsonData options:NSJSONReadingMutableLeaves error:&error];
- [self displayWithParsedDic:rootDic];
- }
小結(jié):這里只是介紹了最簡單的通過網(wǎng)絡得到JSON并解析之的方法。在實際應用中我們可能還要主意在解析時,根據(jù)實際傳輸?shù)臄?shù)據(jù)需要設(shè)置的 option 類型。由于本人的水平有限,如果有錯我還請各位拍磚,并點出來我一定第一時間更正。