zoukankan      html  css  js  c++  java
  • 【iOS】Plist-XML-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的格式例如以下:


    解析代码例如以下:(在异步线程中进行, 最后得到array)
    - (void)loadData
    {
        // 1. url
        NSURL *url = [NSURL URLWithString:@"http://localhost/videos.plist"];
        
        // 2. request
        // timeoutInterval 假设5.0之内没有从server返回结果,就觉得超时了
        /**
         NSURLRequestUseProtocolCachePolicy = 0,            // 使用协议缓存策略(默认)
         NSURLRequestReloadIgnoringLocalCacheData = 1,      // 忽略本地缓存数据(断点续传时使用)
         NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, == 1
         
         // 下面少用
         NSURLRequestReturnCacheDataElseLoad = 2,           // 假设有缓存,就返回缓存数据。否则载入
         NSURLRequestReturnCacheDataDontLoad = 3,           // 死活不载入远程server数据,假设用户没有网络连接时能够使用
         
         // 下面没有实现
         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传入从server接收的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  



  • 相关阅读:
    IOS开发防止图片渲染的方法
    IOS界面通信-代理(协议)传值
    IOS打开其他应用、以及被其他应用打开
    IOS UITableView的分隔线多出问题
    self.view 的不当操作造成死循环
    IOS 导航栏属性设置
    在iOS 8及以后使用UIAlertController 等各种弹出警告通知
    iOS通过URL构建UIImage
    自定义 URL Scheme 完全指南
    Unknown type name 'NSString' 解决方案
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5144094.html
Copyright © 2011-2022 走看看