iOS的Plist-XML-JSON數據解析

jopen 10年前發布 | 52K 次閱讀 JSON JSON開發包

網絡上傳輸數據通用的有XML,JSON等,iOS中也可以用Plist。

要進行數據傳輸,就要首先進行序列化:

1.序列化.
 對象轉換成二進制流.(這個一句話就行)
2.反序列化.
二進制流轉換為對象. (關鍵要弄清楚這個)

JSON:(XML一樣都是用來傳數據的)
輕量級的數據交換格式,正在逐步取代XML.
XML:
結構性的標記語言,易讀.但數據量大.
Plist偶爾用著玩玩:
Mac、iOS中用的多一種格式。

一、應用場景
1、XML的應用場景:
XMPP——即時通訊,KissXML
RSS目前還有少量的企業在使用
開源的WebServices,例如天氣預報等
如果設計好XML的接口,XML的解析并不會太復雜

2、JSON的應用場景:(數據量小,輕量級)
移動開發中絕大多數還是使用JSON
如果自己開發,或者公司后臺接口,最好使用JSON.

二、Plist解析數據
定義一個Plist的格式如下:
20140713013215106.png

解析代碼如下:(在異步線程中進行, 最后得到array)
- (void)loadData
{
    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/videos.plist"];

    // 2. request
    // timeoutInterval 如果5.0之內沒有從服務器返回結果,就認為超時了
    /**
     NSURLRequestUseProtocolCachePolicy = 0,            // 使用協議緩存策略(默認)
     NSURLRequestReloadIgnoringLocalCacheData = 1,      // 忽略本地緩存數據(斷點續傳時使用)
     NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, == 1

     // 以下少用
     NSURLRequestReturnCacheDataElseLoad = 2,           // 如果有緩存,就返回緩存數據,否則加載
     NSURLRequestReturnCacheDataDontLoad = 3,           // 死活不加載遠程服務器數據,如果用戶沒有網絡連接時可以使用

     // 以下沒有實現
     NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // 沒有實現
     NSURLRequestReloadRevalidatingCacheData = 5, // 沒有實現
     */
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:5.0];

    // 3. 網絡異步請求
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        if (connectionError) {
            NSLog(@"錯誤 %@", connectionError);
            return;
        }

        // data是一個plist數據, 對data進行反序列化,解析
        NSArray *array = [NSPropertyListSerialization propertyListWithData:data options:0 format:NULL error:NULL];

        // 刷新數據,在UI線程中更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            //.....
        });
    }];
}

三、XML解析
iOS中XML解析方式的兩種方式(Android中好友pull等) :
1、SAXSimpleAPI for XML
只能讀,不能修改,只能順序訪問,適合解析大型XML解析速度快
常應用于處理大量數據的XML,實現異構系統的數據訪問,實現跨平臺
從文檔的開始通過每一節點移動,定位一個特定的節點
2、DOMDocumentObject Model
不僅能讀,還能修改,而且能夠實現隨機訪問,缺點是解析速度慢,適合解析小型文檔.方便操作.
在內存中生成節點樹操作代價昂貴

XML解析步驟:
1、實例化NSXMLParser傳入從服務器接收的XML數據
2、定義解析器代理
3、解析器解析,通過解析代理方法完成XML數據的解析。

解析XML用到的的代理方法:

1. 開始解析XML文檔

- (void)parserDidStartDocument:

2. 開始解析某個元素,會遍歷整個XML,識別元素節點名稱,如<video>開頭

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

3. 文本節點,得到文本節點里存儲的信息數據。 節點中的數據<video>XXXX</video>

- (void)parser:foundCharacters:

4. 結束某個節點  如</video>開頭

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

注意:在解析過程中,234三個方法會不停的重復執行,直到遍歷完成為止

5.解析XML文檔結束

- (void)parserDidEndDocument:

6.解析出錯

-(void)parser:parseErrorOccurred:

注意: 從網絡上加裝數據是不能用懶加載的.

XML文件格式如下
<?xml version="1.0" encoding="utf-8"?>
<videos>
    <video videoId="1">
        <name>蒼老師1</name>
        <length>320</length>
        <videoURL>/蒼老師1.mp4</videoURL>
        <imageURL>/蒼老師1.png</imageURL>
        <desc>學iOS找蒼老師1</desc>
        <teacher>蒼老師111</teacher>
    </video>

    <video videoId="2">
        <name>蒼老師2</name>
        <length>2708</length>
        <videoURL>/蒼老師2.mp4</videoURL>
        <imageURL>/蒼老師2.png</imageURL>
        <desc>學iOS找蒼老師2</desc>
        <teacher>蒼老師222</teacher>
    </video>
</videos>
解析代碼如下
/** 加載數據 */
- (void)loadData
{
    // 1. url確定資源
    NSURL *url = [NSURL URLWithString:@"http://localhost/videos.xml"];

    // 2. request建立請求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 3. 發送異步請求,新建數據處理隊列,待數據處理完成后,再更新UI
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // 1> 實例化XML解析器
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

        // 2> 設置解析器的代理
        parser.delegate = self;

        // 3> 開始解析
        [parser parse];
    }];
}

#pragma mark - XML解析代理方法
// 1. 開始解析文檔
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    // 為了避免重復刷新數據,可以清空數組
    [self.videoList removeAllObjects];
}

// 2,3,4三個方法會循環被調用
// 2. 開始一個元素(節點)<xxx>
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"video"]) {
        // 創建新的video對象
        self.currentVideo = [[Video alloc] init];

        // 使用KVC賦值
        [self.currentVideo setValue:attributeDict[@"videoId"] forKeyPath:@"videoId"];
    }

    // 在開始第3個方法前,清空字符串內容
    [self.elementM setString:@""];
}

// 3. 發現字符(節點中間內容)
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [self.elementM appendString:string];
}

// 4. 結束節點</xxx>
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"video"]) {
        // 將當前正在解析的節點添加到數組
        [self.videoList addObject:self.currentVideo];
    } else if (![elementName isEqualToString:@"videos"]) {
        [self.currentVideo setValue:self.elementM forKeyPath:elementName];
    }
}

// 5. 結束文檔解析
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"結束文檔解析 %@", self.videoList);
    NSLog(@"%@", [NSThread currentThread]);
    dispatch_async(dispatch_get_main_queue(), ^{
        //UI線程中刷新UI......
    });
}

// 6. 在處理網絡數據時,千萬不要忘記出錯處理
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"錯誤 %@", parseError);
}

四、JSON解析
解析出來的數據需要進行反序列化,方法如下:
[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
JSON解析方便、且輕量級,特別對于手機端,節省流量,快。
JSON格式數據如下:
[
    {"videoId":"1",
    "name":"蒼老師1",
    "length":"320",
    "videoURL":"\/蒼老師1.mp4",
    "imageURL":"\/蒼老師1.png",
    "desc":"學iOS找蒼老師1",
    "teacher":"蒼老師111"},

    {"videoId":"2",
    "name":"蒼老師2",
    "length":"2708",
    "videoURL":"\/蒼老師2.mp4",
    "imageURL":"\/蒼老師2.png",
    "desc":"學iOS找蒼老師2",
    "teacher":"蒼老師222"
    }
]
解析代碼如下:
- (void)loadData
{
    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/videos.json"];

    // 2. request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 3. 發送異步請求
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // data是一個json數據
        // 對data進行反序列化,解析
        NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

        // 刷新數據,更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            //在主線程中更新UI......
        });
    }];
}


轉載請注明出處:http://blog.csdn.net/xn4545945  

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!