JSON解析
JSON簡(jiǎn)單介紹
JSON是一種輕量級(jí)的數(shù)據(jù)格式席楚,一般用于數(shù)據(jù)交互蓖议。服務(wù)器返回給客戶端的數(shù)據(jù),一般都是JSON格式或者XML格式(文件下載除外)
相關(guān)說(shuō)明
- JSON的格式很像OC中的字典和數(shù)組
- 標(biāo)準(zhǔn)JSON格式key必須是雙引號(hào)
JSON解析方案
- 第三方框架 JSONKit\SBJSON\TouchJSON
- 蘋果原生(NSJSONSerialization)
JSON解析相關(guān)代碼
- json數(shù)據(jù)->OC對(duì)象
//把json數(shù)據(jù)轉(zhuǎn)換為OC對(duì)象
-(void)jsonToOC {
//1. 確定url路徑
NSURL *url = [NSURL URLWithString:@"URL字符串"];
//2.創(chuàng)建一個(gè)請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.使用NSURLConnection發(fā)送一個(gè)異步請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.當(dāng)接收到服務(wù)器響應(yīng)的數(shù)據(jù)后矩屁,解析數(shù)據(jù)(JSON--->OC)
/*
第一個(gè)參數(shù):要解析的JSON數(shù)據(jù)纪隙,是NSData類型也就是二進(jìn)制數(shù)據(jù)
第二個(gè)參數(shù): 解析JSON的可選配置參數(shù)
NSJSONReadingMutableContainers 解析出來(lái)的字典和數(shù)組是可變的
NSJSONReadingMutableLeaves 解析出來(lái)的對(duì)象中的字符串是可變的 iOS7以后有問(wèn)題
NSJSONReadingAllowFragments 被解析的JSON數(shù)據(jù)如果既不是字典也不是數(shù)組, 那么就必須使用這個(gè)
*/
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict);
}];
}
- OC對(duì)象->JSON對(duì)象
//1.要轉(zhuǎn)換成JSON數(shù)據(jù)的OC對(duì)象*這里是一個(gè)字典
NSDictionary *dictM = @{ @"name":@"flame",
@"age":@20,
@"height":@1.80
};
//2.OC->JSON
/*
注意:可以通過(guò)+ (BOOL)isValidJSONObject:(id)obj;方法判斷當(dāng)前OC對(duì)象能否轉(zhuǎn)換為JSON數(shù)據(jù)
具體限制:
1.obj 是NSArray 或 NSDictionay 以及他們派生出來(lái)的子類
2.obj 包含的所有對(duì)象是NSString,NSNumber,NSArray,NSDictionary 或NSNull
3.字典中所有的key必須是NSString類型的
4.NSNumber的對(duì)象不能是NaN或無(wú)窮大
*/
/*
第一個(gè)參數(shù):要轉(zhuǎn)換成JSON數(shù)據(jù)的OC對(duì)象,這里為一個(gè)字典
第二個(gè)參數(shù):NSJSONWritingPrettyPrinted對(duì)轉(zhuǎn)換之后的JSON對(duì)象進(jìn)行排版碗硬,無(wú)意義
*/
NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];
//3.打印查看Data是否有值
/*
第一個(gè)參數(shù):要轉(zhuǎn)換為String的二進(jìn)制數(shù)據(jù)
第二個(gè)參數(shù):編碼方式瓤湘,通常采用NSUTF8StringEncoding
*/
NSString *strM = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",strM);
- OC對(duì)象和JSON數(shù)據(jù)格式之間的一一對(duì)應(yīng)關(guān)系
//OC對(duì)象和JSON數(shù)據(jù)之間的一一對(duì)應(yīng)關(guān)系
-(void)oCWithJSON{
//JSON的各種數(shù)據(jù)格式
//NSString *test = @"\"flame\"";
//NSString *test = @"true";
NSString *test = @"{\"name\":\"flame\"}";
//把JSON數(shù)據(jù)->OC對(duì)象,以便查看他們之間的一一對(duì)應(yīng)關(guān)系
//注意點(diǎn):被解析的JSON數(shù)據(jù)如果既不是字典也不是數(shù)組(比如是NSString), 那么就必須使用這 NSJSONReadingAllowFragments
id obj = [NSJSONSerialization JSONObjectWithData:[test dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
NSLog(@"%@", [obj class]);
/*
JSON數(shù)據(jù)格式和OC對(duì)象的一一對(duì)應(yīng)關(guān)系
{} -> 字典
[] -> 數(shù)組
"" -> 字符串
10/10.1 -> NSNumber
true/false -> NSNumber
null -> NSNull
*/
}}
- 如何查看復(fù)雜的JSON數(shù)據(jù)
- 方法一: 在線格式化http://tool.oschina.net/codeformat/json
- 方法二: 把解析后的數(shù)據(jù)寫plist文件,通過(guò)plist文件可以直觀的查看JSON的層次結(jié)構(gòu)恩尾。
[dictM writeToFile:@"文件路徑/文件名.plist" atomically:YES];
字典轉(zhuǎn)模型框架
- 相關(guān)框架
- Mantle 需要繼承自MTModel
- JSONModel 需要繼承自JSONModel
- MJExtension 不需要繼承弛说,無(wú)代碼侵入性
- 自己設(shè)計(jì)和選擇框架時(shí)需要注意的問(wèn)題
- 侵入性
- 易用性,是否容易上手
- 擴(kuò)展性特笋,很容易給這個(gè)框架增加新的功能
XML解析
XML簡(jiǎn)單介紹
XML:可擴(kuò)展標(biāo)記語(yǔ)言
http://baike.baidu.com/link?url=TbqIa8egIx6fbzxIPnajB253ae80Nli9O7sLob2LW9zt-lN1WKxuhfV5srC-lyaJpBgQXezNbHN8-QDmMY46dqQSI9SfOrzgKxB8GXCuhtmmoC1gpkqmJ1Z1PhWgV_TDXML解析
- XML解析的兩種方式
- SAX:從根元素開(kāi)始剃浇,按順序一個(gè)元素一個(gè)元素的往下解析,可用于解析大猎物、小文件
- DOM:一次性將整個(gè)XML文檔加載到內(nèi)存中虎囚,適合較小的文件
- 解析XML的工具
- 蘋果原生NSXMLParser:使用SAX方式解析,使用簡(jiǎn)單
- 第三方框架
libxml2:純C語(yǔ)言的蔫磨,默認(rèn)包含在iOS SDK中淘讥,同時(shí)支持DOM和SAX的方式解析 GDataXML:采用DOM方式解析,該框架由Google開(kāi)發(fā)堤如,是基于xml2的
- XML解析代碼
- 使用NSXMLParser解析XML步驟和代理方法
//解析步驟:
//4.1 創(chuàng)建一個(gè)解析器
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
//4.2 設(shè)置代理
parser.delegate = self;
//4.3 開(kāi)始解析
[parser parse];
//1.開(kāi)始解析XML文檔
-(void)parserDidStartDocument:(nonnull NSXMLParser *)parser
//2.開(kāi)始解析XML中某個(gè)元素的時(shí)候調(diào)用蒲列,比如<video>
-(void)parser:(nonnull NSXMLParser *)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict{
if ([elementName isEqualToString:@"videos"]) { return; }
//字典轉(zhuǎn)模型
TYVideo *video = [TYVideo objectWithKeyValues:attributeDict];
[self.videos addObject:video];
}
//3.當(dāng)某個(gè)元素解析完成之后調(diào)用窒朋,比如</video>
-(void)parser:(nonnull NSXMLParser *)parser didEndElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName
//4.XML文檔解析結(jié)束
-(void)parserDidEndDocument:(nonnull NSXMLParser *)parser
- 使用GDataParser解析XML的步驟和方法
//配置環(huán)境
// 1 先導(dǎo)入框架,然后按照框架使用注釋配置環(huán)境
// 2 GDataXML框架是MRC的蝗岖,所以還需要告訴編譯器以MRC的方式處理GDataXML的代碼
//加載XML文檔(使用的是DOM的方式一口氣把整個(gè)XML文檔都吞下)
GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];
//獲取XML文檔的根元素侥猩,根據(jù)根元素取出XML中的每個(gè)子元素
NSArray * elements = [doc.rootElement elementsForName:@"video"];
//取出每個(gè)子元素的屬性并轉(zhuǎn)換為模型
for (GDataXMLElement *ele in elements) {
TYVideo *video = [[TYVideo alloc]init];
video.name = [ele attributeForName:@"name"].stringValue;
video.length = [ele attributeForName:@"length"].stringValue.integerValue;
video.url = [ele attributeForName:@"url"].stringValue;
video.image = [ele attributeForName:@"image"].stringValue;
video.ID = [ele attributeForName:@"id"].stringValue;
//把轉(zhuǎn)換好的模型添加到tableView的數(shù)據(jù)源self.videos數(shù)組中
[self.videos addObject:video];
}
- 多值參數(shù)和中文輸出問(wèn)題
- 多值參數(shù)如何設(shè)置請(qǐng)求路徑
/*
如果一個(gè)參數(shù)對(duì)應(yīng)著多個(gè)值,那么直接按照"參數(shù)=值&參數(shù)=值"的方式拼接
*/
-(void)test{
//1.確定
URL NSURL *url = [NSURL URLWithString:@"URL字符串"];
//2.創(chuàng)建請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.發(fā)送請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析
NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
}
- 如何解決字典和數(shù)組中輸出亂碼的問(wèn)題
給字典和數(shù)組添加一個(gè)分類抵赢,重寫descriptionWithLocale方法欺劳,在該方法中拼接元素格式化輸出。 -(nonnull NSString *)descriptionWithLocale:(nullable id)locale