zoukankan      html  css  js  c++  java
  • iOS开发之JSON & XML

    1、概述

    JSON

    (1) 作为一种轻量级的数据交换格式,正在逐步取代XML,成为网络数据的通用格式

    (2) 基于JavaScript的一个子集

    (3) 易读性略差,编码手写难度大,数据量小

    (4) JSON格式取代了XML给网络传输带来了很大的便利,但是却没有了XML的一目了然,尤其是JSON数据很长的时候,我们会陷入繁琐复杂的数据节点查找中

    XML

    (1)可扩展标记语言

    (2)用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言

    (3)易读性高,编码手写难度小,数据量大

    客户端与服务器数据传输示意图:

    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  在内存中生成节点树操作代价昂贵

    1、         解析步骤:

    【备注】属性:

    @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:

    注意:在解析过程中,2、3、4三个方法会不停的重复执行,直到遍历完成为止

    // 5. 解析XML文档结束

    - (void)parserDidEndDocument:

    // 6. 解析出错

    - (void)parser:parseErrorOccurred:

  • 相关阅读:
    Emacs 使用YASnippet
    odbc备忘
    Emacs 矩形编辑
    ftp by libcurl
    emacsshell
    Emacs cnblogs 代码着色
    Emacs下的Man
    #include ""还是<>
    三种*
    应对Maze勒索攻击的最佳实践分享
  • 原文地址:https://www.cnblogs.com/lifengfneg/p/4774024.html
Copyright © 2011-2022 走看看