iOS開發之JSON & XML

1、概述javascript

JSONphp

(1) 做爲一種輕量級的數據交換格式,正在逐步取代XML,成爲網絡數據的通用格式java

(2) 基於JavaScript的一個子集數組

(3) 易讀性略差,編碼手寫難度大,數據量小服務器

(4) JSON格式取代了XML給網絡傳輸帶來了很大的便利,可是卻沒有了XML的一目瞭然,尤爲是JSON數據很長的時候,咱們會陷入繁瑣複雜的數據節點查找中網絡

XMLapp

(1)可擴展標記語言異步

(2)用於標記電子文件使其具備結構性的標記語言,能夠用來標記數據、定義數據類型,是一種容許用戶對本身的標記語言進行定義的源語言async

(3)易讀性高,編碼手寫難度小,數據量大ide

客戶端與服務器數據傳輸示意圖:

 

2JSON格式說明

對象

n  {}

n  格式 {key : value, key : value,...} 的鍵值對的結構

n  能夠反序列化爲OC中的NSDictionary

數組

n  []

n  格式 ["java","javascript","vb",...]

n  能夠反序列化爲OC中的NSArray

提示

n  JSON的數據格式與OC中的快速包裝方法很是相似

n  JSON的數據格式一樣支持嵌套

3、解析服務器端返回JSON數據

n  從iOS 5開始,使用NSJSONSerialization對JSON解析

n  其餘常見的三種JSON解析第三方庫:

n  SBJson     由於API簡單易用,可能還會有一些應用中留存

n  JSONKit   JSONKit的開發者稱:JSONKit的性能優於蘋果

n  TouchJson

4JSON的序列化和反序列化

反序列化

[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

例如:

- (void)getLogon2

{

[self.view endEditing:YES];

 // 1. URL

NSString *urlStr =

[NSString stringWithFormat:@"http://192.168.40.2/

login.php?username=%@&password=%@", self.userName.text, self.userPwd.text];

   

    // 若是URL中包含中文字符或者特殊字符,例如空格,須要添加百分號轉義

urlStr =

[urlStr stringByAddingPercentEscapesUsingEncoding:

NSUTF8StringEncoding];

   

    NSURL *url = [NSURL URLWithString:urlStr];

   

    // 2. NSURLRequest

    /**

     參數:

     timeoutInterval:開發中必定要指定超時時長,默認60秒,一般靠考慮到用戶的網絡環境,能夠設置到10~20秒,不能太長,也不能過短

     */

    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:5.0f];

   

    // 3. 發送異步請求

[NSURLConnection sendAsynchronousRequest:request queue:

[[NSOperationQueue alloc] init] completionHandler:

^(NSURLResponse *response, NSData *data, NSError *connectionError) {

       

        if (connectionError) {

            [self showAlertViewWithMsg:@"網絡不給力"];

           

            return;

        } else {

            // 將接收到的二進制數據反序列化爲數據字典

            NSDictionary *dict =

[NSJSONSerialization JSONObjectWithData:data

options:nil error:NULL];

           

            LoginUser *user = [[LoginUser alloc] initWithDict:dict];

           

            // 若是用戶有頭像就加載頭像

            if (user.userImage) {

                dispatch_async(dispatch_get_main_queue(), ^{

                    self.imageView.image =

[user loadImageWithURL:user.userImage];

                });

            }

           

            // 用戶登陸錯誤?不會網絡鏈接失敗!

            if (!user.userId) {

                [self showAlertViewWithMsg:@"用戶名或者密碼不正確"];

               

                return;

            }

           

            [[NSOperationQueue mainQueue]

addOperationWithBlock:^{

                self.logonResult.text = @"登陸完成";

            }];

        }

    }];

}

 

序列化

[NSJSONSerialization dataWithJSONObject:array options:0 error:NULL];

5NSXMLParser

1NSXMLParser解析方法

n  NSXMLParser是SAX方法解析

SAXSimple API for XML

n  只能讀,不能修改,只能順序訪問,適合解析大型XML,解析速度快

n  常應用於處理大量數據的XML,實現異構系統的數據訪問,實現跨平臺

n  從文檔的開始經過每一節點移動,定位一個特定的節點

DOMDocument Object Model

n  不只能讀,還能修改,並且可以實現隨機訪問,缺點是解析速度慢,適合解析小型文檔

n  通常應用與小型的配置XML,方便操做

n  爲載入到內存的文檔節點創建類型描述,呈現可橫向移動、潛在巨大的樹型結構

n  在內存中生成節點樹操做代價昂貴

 

一、         解析步驟:

【備註】屬性:

@property (nonatomic, strong) NSMutableArray *dataList;

// 來回拼接

@property (nonatomic, strong) NSMutableString *elementString;

// 當前視頻信息的對象

@property (nonatomic, strong) Video *v;

還要遵照代理協議:NSXMLParserDelegate

示例代碼:

- (IBAction)loadData

{

// 1. URL

NSURL *url =

[NSURL URLWithString:@"http://localhost/videos.php"];

    // 2. Request

    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0f];

    // 3. 發送請求

[NSURLConnection sendAsynchronousRequest:request queue:

[[NSOperationQueue alloc] init]completionHandler:

^(NSURLResponse *response, NSData *data, NSError *connectionError) {

//第一步:實例化NSXMLParser,傳入從服務器接收的XML數據

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

//第二步:定義解析器代理

  parser.delegate = self;

//第三步:解析器解析

[parser parse];

}];

}

 

//第四步:經過解析代理方法完成XML數據的解析

#pragma mark 1. 開始

- (void)parserDidStartDocument:(NSXMLParser *)parser

{

    // 準備工做

    // 1> dataList

    if (!self.dataList) {

        self.dataList = [NSMutableArray array];

    } else {

        [self.dataList removeAllObjects];

    }

   

    // 2> elementString

    if (!self.elementString) {

        self.elementString = [NSMutableString string];

    } else {

        // 清空可變字符串不要設置成nil,使用setString只是清空內容,下次不會再次實例化

        [self.elementString setString:@""];

    }

}

 

#pragma mark 2. 全部開始一個節點:<element>

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict

{

    // 若是是<video>新建對象

    if ([elementName isEqualToString:@"video"]) {

        self.v = [[Video alloc] init];

        self.v.videoId = attributeDict[@"videoId"];

    }

   

    // 每開始一個新節點以前都清空elementString

    // 避免上一次的結果被重複拼接

    [self.elementString setString:@""];

}

 

#pragma mark 3. 查找內容,可能會重複屢次

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

{

    // 拼接字符串

    [self.elementString appendString:string];

}

 

#pragma mark 4. 節點結束 </element>

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

{

    NSLog(@"結束節點 %@", elementName);

    // 判斷若是是<name>要複製

    if ([elementName isEqualToString:@"video"]) {

        [self.dataList addObject:self.v];

    } else if (![elementName isEqualToString:@"videos"]) {

        [self.v setValue:self.elementString forKey:elementName];

    }

 

}

 

#pragma mark 5. 文檔結束

- (void)parserDidEndDocument:(NSXMLParser *)parser

{

    NSLog(@"解析結束 %@ %@", self.dataList, [NSThread currentThread]);

   

    dispatch_async(dispatch_get_main_queue(), ^{

        [self.tableView reloadData];

       

        // 關閉刷新控件的刷新

        [self.refreshControl endRefreshing];

    });

}

 

#pragma mark 6. 出錯處理

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError

{

    NSLog(@"%@", parseError.localizedDescription);

}

3NSXMLParser解析代理方法

// 1. 開始解析XML文檔

- (void)parserDidStartDocument:

// 2. 開始解析某個元素,會遍歷整個XML,識別元素節點名稱

- (void)parser:didStartElement:namespaceURI:qualifiedName:attributes:

// 3. 文本節點,獲得文本節點裏存儲的信息數據,對於大數據可能會接收屢次!爲了節約內存開銷

- (void)parser:foundCharacters:

// 4. 結束某個節點,存儲從parser:foundCharacters:方法中獲取到的信息

- (void)parser:didEndElement:namespaceURI:qualifiedName:

注意:在解析過程當中,二、三、4三個方法會不停的重複執行,直到遍歷完成爲止

// 5. 解析XML文檔結束

- (void)parserDidEndDocument:

// 6. 解析出錯

- (void)parser:parseErrorOccurred:

相關文章
相關標籤/搜索