iOS开发——XML/JSON数据解析
?
?
?
?
NSJSONSerialization
?
?
接下來就正式開始。蘋果官方給出的解析方式是性能最優越的,雖然用起來稍顯復雜。
首先我們在上面已經有了我希望得到的信息的網站的API給我們的URL,在OC中,我要加載一個NSURL對象,來向網站提交一個Request。到這里需要特別注意了,iOS9的時代已經來臨,我們先前在舊版本中使用的某些類或者方法都已經被蘋果官方棄用了。剛剛我們向網站提交了一個Request,在以往,我們是通過NSURLConnection中的sendSynchronousRequest方法來接受網站返回的Response的,但是在iOS9中,它已經不再使用了。從官方文檔中,我們追根溯源,找到了它的替代品——NSURLSession類。這個類是iOS7中新的網絡接口,蘋果力推之,并且現在用它完全替代了NSURLConnection。關于它的具體用法,還是蠻簡單的,直接上代碼(ViewController.m文件):
原文鏈接:http://www.jianshu.com/p/a54d367adb2a
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。 #import "ViewController.h"@interface ViewController () @property (retain, nonatomic) IBOutlet UITextView *textView; @property (nonatomic, strong) NSMutableDictionary *dic; @property (nonatomic,strong) NSString *text; @end @implementation ViewController - (IBAction)NSJson:(UIButton *)sender { //GCD異步實現 dispatch_queue_t q1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(q1, ^{ //加載一個NSURL對象 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://api.douban.com/v2/movie/subject/25881786"]]; //使用NSURLSession獲取網絡返回的Json并處理 NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){ //從網絡返回了Json數據,我們調用NSJSONSerialization解析它,將JSON數據轉換為Foundation對象(這里是一個字典) self.dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSString *title = [self.dic objectForKey:@"original_title"]; NSMutableArray *genresArray = [self.dic objectForKey:@"genres"]; NSString *genres = [NSString stringWithFormat:@"%@/%@", [genresArray objectAtIndex:0], [genresArray objectAtIndex:1]]; NSString *summary = [self.dic objectForKey:@"summary"]; self.text = [NSString stringWithFormat:@"電影名稱:\n%@\n體裁:\n%@\n劇情簡介:\n%@", title, genres, summary]; //更新UI操作需要在主線程 dispatch_async(dispatch_get_main_queue(), ^{ self.textView.text = self.text; }); }]; //調用任務 [task resume]; }); }
NSXMLParse
?
?
關于XML,有兩種解析方式,分別是SAX(Simple API for XML,基于事件驅動的解析方式,逐行解析數據,采用協議回調機制)和DOM(Document Object Model ,文檔對象模型。解析時需要將XML文件整體讀入,并且將XML結構化成樹狀,使用時再通過樹狀結構讀取相關數據,查找特定節點,然后對節點進行讀或寫)。蘋果官方原生的NSXMLParse類庫采用第一種方式,即SAX方式解析XML,它基于事件通知的模式,一邊讀取文檔一邊解析數據,不用等待文檔全部讀入以后再解析,所以如果你正打印解析的數據,而解析過程中間出現了錯誤,那么在錯誤節點之間的數據會正常打印,錯誤后面的數據不會被打印。解析過程由NSXMLParserDelegate協議方法回調。
原文鏈接:http://www.jianshu.com/p/a54d367adb2a
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。
我們遵循MVC,首先我們創建模型,新建一個person類,存放XML文件中描述的person屬性。再來一個解析XML文件的工具類XMLUtil,我們在里面實現文件的獲取,代理方法的實現。
先來看這兩個類的代碼:
?
//person.h#import <Foundation/Foundation.h>@interface person : NSObject @property (nonatomic, copy) NSString *pid; @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *sex; @property (nonatomic, copy) NSString *age; @end//XMLUtil.h#import <Foundation/Foundation.h> #import "person.h" //聲明代理 @interface XMLUtil : NSObject<NSXMLParserDelegate> //添加屬性 @property (nonatomic, strong) NSXMLParser *par; @property (nonatomic, strong) person *person; //存放每個person @property (nonatomic, strong) NSMutableArray *list; //標記當前標簽,以索引找到XML文件內容 @property (nonatomic, copy) NSString *currentElement; //聲明parse方法,通過它實現解析 -(void)parse; @end //XMLUtil.m #import "XMLUtil.h" @implementation XMLUtil - (instancetype)init{ self = [super init]; if (self) { //獲取事先準備好的XML文件 NSBundle *b = [NSBundle mainBundle]; NSString *path = [b pathForResource:@"test" ofType:@".xml"]; NSData *data = [NSData dataWithContentsOfFile:path]; self.par = [[NSXMLParser alloc]initWithData:data]; //添加代理 self.par.delegate = self; //初始化數組,存放解析后的數據 self.list = [NSMutableArray arrayWithCapacity:5]; } return self; } //幾個代理方法的實現,是按邏輯上的順序排列的,但實際調用過程中中間三個可能因為循環等問題亂掉順序 //開始解析 - (void)parserDidStartDocument:(NSXMLParser *)parser{ NSLog(@"parserDidStartDocument..."); } //準備節點 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict{ self.currentElement = elementName; if ([self.currentElement isEqualToString:@"student"]){ self.person = [[person alloc]init]; } } //獲取節點內容 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if ([self.currentElement isEqualToString:@"pid"]) { [self.person setPid:string]; }else if ([self.currentElement isEqualToString:@"name"]){ [self.person setName:string]; }else if ([self.currentElement isEqualToString:@"sex"]){ [self.person setSex:string]; }else if ([self.currentElement isEqualToString:@"age"]){ [self.person setAge:string]; } } //解析完一個節點 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName{ if ([elementName isEqualToString:@"student"]) { [self.list addObject:self.person]; } self.currentElement = nil; } //解析結束 - (void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"parserDidEndDocument..."); } //外部調用接口 -(void)parse{ [self.par parse]; } @end
OK,總算是大功告成,如果對代理的使用比較熟悉的話,這部分內容其實還蠻簡單的。如果被代碼轉來轉去弄暈了的話可以在每個block的最后都加一個打印輸出,做好標記,你就能弄懂程序的執行順序了。
我們點擊NSXMLParse,有了!
轉載于:https://www.cnblogs.com/supper-Ho/p/6209210.html
總結
以上是生活随笔為你收集整理的iOS开发——XML/JSON数据解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基础编程题之MP3
- 下一篇: Codevs 3269 混合背包