IOS开发之网络篇第一章:数据交换格式

网络通信最常用的数据通信格式是xml和Json,各有各的好处,不管怎样,这种的格式,我们在开发的过程中经常使用的,现在就这两种格式进行记录笔记,以下内容不做详细分析,只针对如何应用各种读写工具进行对xml和json内容的操作

xml

解析XML文件现在有两种主流的,SAX和DOM

  • SAX-基于时间事件驱动,意思就是读取的过程中,是由上往下的读取xml文件,当遇到节点的时候,触发相应的事件,使用上比较快,缺点是不能修改文件内容
  • DOM-以树状形式加载,加载后存放在内存当中,所以如果文件大,读取的时间就会比较长,但是可修改文件

IOS的SDK提供了两个框架,还有些第三方框架,这里只介绍2种NSXML和TBXML

  • NSXML-它是用Object-C语言编写,只支持SAX解析框架
  • libxml2
  • TBXML-使用DOM的解析框架(据说很快,有时间测试一下)
  • TouchXML
  • KissXML
  • TinyXML
  • GDataXML

现在有一个xml文件,现在通过NSXML方式来读取,我们另外写了一个类,用于读写xml的

第一种介绍的是NSXML

NodeText.xml

<?xml version="1.0" encoding="UTF-8"?>
<Notes>
    <Note id="1"> 
   <Name>8点􏳸到􏳹􏳺</Name> 
   <UserID>tony</UserID>
    </Note>
    <Note id="1"> 
   <Name>8点􏳸到􏳹􏳺</Name> 
   <UserID>tony</UserID>
    </Note>
</Notes>        

 

下面的这个类是是用作读写XML用的,必须使用委托NSXMLParserDelegate,这里有两个方法,一个是初次化initWithURL:需要提供文件地址,另外一个方法是parser,这个方法就是开始解析xml文件的入口

XMLReader.h文件

#import <Foundation/Foundation.h>

@interface XmlReader : NSObject<NSXMLParserDelegate>

@property(nonatomic)NSMutableDictionary *dict;

-(id)initWithURL:(NSURL *)url;

-(void)parser;

@end

 

具体的实现如下

XMLReader.m,NSXMLParserDelegate委托包含很多个方法可以,这里主要复写了以下几个方法

  • - (void)parserDidStartDocument:(NSXMLParser *)parser

    •   当文档开始的时候会调用,只读一次
  • - (void)parserDidEndDocument:(NSXMLParser *)parser

    •   当文档解析结束的时候调用,只读一次
  • - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict

    •   当节点开始的时候调用
  • -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

    •   当节点结束的时候调用
  • -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

    •   当读取到节点里面的字符串的时候调用
@interface XmlReader()
@property(nonatomic)NSURL *url;
@end

@implementation XmlReader

-(id)initWithURL:(NSURL *)url
{
    
    self = [super init];
    if (self) {
        self.url = url;
        
    }
    return self;
}

-(void)parser
{
    NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:self.url];
    parser.delegate = self;
    BOOL b = [parser parse];
}


- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    self.dict = [[NSMutableDictionary alloc]init];
}
// sent when the parser begins parsing of the document.
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict
{
    
    NSLog(@"%@",elementName);
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    NSLog(@"%@",string);
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"%@",elementName);
}

@end

 

第二种介绍的是TBXML

这个是一个第三方提供的读取方式,所以需要导入代码工程,可以到https://github.com/71squared/TBXML下载源码,下载的zip包或者hub同步下载,我使用的是下载zip包,下载好后解压,会得到一大堆文件,但这里只需要提取TBXML.h和TBXML.m文件即可,把他们考到工程里面,直接使用即可。根据一些网上有些不同的经验之谈,有的因不支持ARC机制,而报的错,有的是因为工程没有导入libz.dylib包而出错,不管怎样,没有包的直接导入就行,不支持ARC就找找网络的文章就可以解决,我这里出现了另外一个情况,就是TBXML.h文件少导入了fundation包,所以导致报错了,没有找到NSObject

这些都配置好后,就可以使用了,这里我写了另外的一个类,用作读取信息xml用的,代码如下

XmlReaderTBXML.h文件

#import <Foundation/Foundation.h>
#import "TBXML.h"

@interface XmlReaderTBXML : NSObject

@property (strong,nonatomic) NSMutableArray *notes;

//开始解析方法
-(void)start;

@end

 

XmlReaderTBXML.h文件

#import "XmlReaderTBXML.h"

@implementation XmlReaderTBXML


-(void)start
{
    self.notes = [[NSMutableArray alloc]init];
    
    TBXML *tbxml = [[TBXML alloc]initWithXMLFile:@"NodeTest.xml" error:nil];
    
    TBXMLElement * root = tbxml.rootXMLElement;
    if (root) {
        TBXMLElement * noteElement = [TBXML childElementNamed:@"Note"
                                                parentElement:root];
        while ( noteElement != nil) {
            NSMutableDictionary *dict = [NSMutableDictionary new];
            TBXMLElement *CDateElement = [TBXML childElementNamed:@"CDate" parentElement:noteElement];
            if ( CDateElement != nil) {
                NSString *CDate = [TBXML textForElement:CDateElement];
                [dict setValue:CDate forKey:@"CDate"];
            }
            TBXMLElement *ContentElement = [TBXML childElementNamed:@"Content" parentElement:noteElement];
            if ( ContentElement != nil) {
                NSString *Content = [TBXML textForElement:ContentElement];
                [dict setValue:Content forKey:@"Content"];
            }
            TBXMLElement *UserIDElement = [TBXML childElementNamed:@"UserID" parentElement:noteElement];
            if ( UserIDElement != nil) {
                NSString *UserID = [TBXML textForElement:UserIDElement];
                [dict setValue:UserID forKey:@"UserID"];
            }
            //ID属性
            NSString *_id = [TBXML valueOfAttributeNamed:@"id" forElement:noteElement error:nil];
            [dict setValue:_id forKey:@"id"];
            [_notes addObject:dict];
            noteElement = [TBXML nextSiblingNamed:@"Note" searchFromElement:noteElement];
            
        }
        
    }
    NSLog(@"解析完成...");
   
    self.notes = nil;
}
@end

在这个start方法中就是读取xml的过程,非常简单,就不作介绍了

 

 

JSON

Json是一个轻量级的数据交换格式,这个只是对比起XML来说的,在网络传输当中,JSON因为不像XML那样需要成双成对的节点结构,一个开节点,一个闭节点,所以它比XML的字节数会减少许多,Json的结构如下,主要由两个符号组成

  • {}=字典Dictionary,{"Item_1":"LL","Item_2":123,"Item_3":true},在IOS里面,对Json的Key有格式要求,必须要双引号,不能是单引号,更不能没有引号,Key跟value之间以冒号(:)分割,两组键值对之间以逗号(,)相隔
  • []=数组Array,["Item_1","Item_2","Item_3"],项与项之间以都好(,)相隔

这里解码的方式有以下几种,我们这里就只学NSJSONSerialization

  • SBJSON
  • TouchJSON
  • YAJL
  • JSONKit
  • NextiveJson
  • NSJSONSerialization ,它是在IOS 5.0后才被加入SDK中使用

这个是JSON格式的文件

JText.json

{
    "Item_1":"测试1",
    "Item_2":"测试2",
    "Item_3":"测试3"
}

 

通过以下代码就能获取到JSON内容

首先要把文件转换成NSData,其中第二行代码就是转换为NSData,第四行中就是主要的解析json内容的代码,其中一个参数是options,这里的常量参数有3种

  • NSJSONReadingMutableContainers 一般都使用这个
  • NSJSONReadingMutableLeaves 这个的用意不是很明确,网上说的都是笼统的,只是纸上谈兵,具体应用是怎样,好像没有一个说法,如果知道的同学可以评论一下
  • NSJSONReadingAllowFragments 这个的用意不是很明确,网上说的都是笼统的,只是纸上谈兵,具体应用是怎样,好像没有一个说法,如果知道的同学可以评论一下
NSString *path = [[NSBundle mainBundle]pathForResource:@"JText" ofType:@"json"];
NSData *data = [[NSData alloc]initWithContentsOfFile:path];
NSError *err;
id jsonOBj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
    
NSLog(@"%@",jsonOBj);

得到一个对象后,可以进行多态转换,就可以获取到里面的值

if ([jsonOBj isKindOfClass:[NSDictionary class]]){

     NSDictionary *dictionary = (NSDictionary *)jsonOBj;
}

 

posted @ 2016-03-09 10:59  长命百岁  阅读(269)  评论(0编辑  收藏  举报