iOS网络高级编程—网络功能(生产与解析请求/负载)

1 Web Service协议

在开始负载相关内容之前,我们先来了解下Web Service协议。因为负载遵循于Web Service协议。

Web Service协议中的协议指的是多种网络系统进行有结构的信息通讯遵循的格式与规则。

有2种比较重要的协议。分别是SOAP根REST。

1.1 SOAP(Simple Object Access Protocol)简单对象访问协议

通常用XML实现,于1998年被微软提出,适用于企业交互解决方案。但不适用于移动设备。这里不详细介绍。

1.2 REST(Representational State Transfer)表述性状态转移

于2000年被Roy Fielding提出的一种架构设计风格。实现REST风格的服务叫做RESTful Service。随便搜索一下就能发现REST已经随着Web2.0的春风风靡起来。

REST的中心议题是具有全局标识符的资源,URI。

REST还有两个关键属性:无状态和可缓存。无状态交互要求请求包含所有必要的信息来理解上下文。因为URI的原因。客户端可以更加轻松地缓存响应。


在扯完高大上的Web Service协议之后,终于要入正题。

2 负载

指的是在服务的请求响应事务中交换的数据。应该就是request的参数与response的contain了。

负载的数据格式一般有:XML(可扩展标记性语言)、JSON(JavaScript对象符号)、超文本标记语言(HTML)。

2.1 XML介绍

一种标记语言,开始于1996年。前面介绍的SOAP就主要是用的XML。因为历史原因,目前挺多大型软件互联网系统都还在采用XML的数据格式。可能因为替换的成本过大,而且效果没有特别明显的提升,就保留了。

XML由标签、属性与元素构成。有3种类型的标签:起始标签(<person>)、结束标签(</person>)、空标签(<noContact />)。根据这3种标签可自定义不同的数据。

2.2 JSON介绍

主角,目前最流行的网络数据格式。正式记载是2006年07月发布的RFC4627的application/json媒体类型。这个时候也是iPhone发布及移动互联网浪潮的开始。多么巧合。

JSON虽然小巧,但是也有一些基本的格式规则,如下:

  • 数字:无双引号。
  • 布尔:取值为true或false,无双引号。
  • 字符串:双引号括起。
  • 数组:方括号包围的以逗号分隔的列表。
  • 对象:花括号包围的键值对集合。OC中的字典。
  • null:无双引号。

2.3 HTML介绍

也是一种标记语言。一般用于页面展示中,貌似用于数据传输比较少。

最近随着大热的HTML5定稿,不断在引人注目啊。~


3 解析负载

3.1 XML解析

XML有两种解析方式:SAX(Simple API for XML)与DOM(Document Object Model)。

SAX,是事件驱动型,会顺序解析XML文档中的元素,一次处理一个元素。

DOM,会讲整个XML文档以可遍历的节点树的形式读取到内存中。

iOS自带了两个原生的XML解析器,分别是NSXMLParser与libxml。

NSXMLParser,OC SAX解析器,在遇到元素、属性、CDate块、注释与文档起始和结束事件是会调用各种委托方法。NSXMLParser Class Reference from Apple Doc

NSXMLParser中有几个重要的回调函数:

  • parserDidStartDocument,开始解析时回调。
  • parserDidEndDocument,解析到文档末尾时回调。
  • parser:didStartElement:namespaceURI:qualifiedName:attributes:,开始处理新元素时调用。
  • parser:foundCharacter:,从元素中读取内容时调用。
  • parser:didEndElement:namespaceURI:qualifiedName:,元素关闭时调用。
    libxml,开源、基于C语言的API,支持SAX与DOM解析。libxml SAX解析类似于NSXMLParser,在遇到某些事件时会进行大量回调。libxml DOM会将整个XML文档读取为节点树,可以通过XPath(XML Path Language)遍历与查询。libxml2 xpath函数调用示例

3.2 HTML解析

HTML在实际中并不常用,而且解析负责,这里不做描述。

3.3 JSON解析

在iOS5之前还没有原生的API支持JSON解析。还需要通过如JSON Kit等第三方库来支持。iOS5之后,Apple提供了NSJSONSerialization类。

NSJSONSerialization类提供了2个方法:JSONObjectWithData:options:error:和JSONObjectWithStream:options:error:,这两个方法从名称可以理解出不同点在data和stream,Apple官网给出的解释分别是:”A data object containing JSON data.”和”A stream from which to read JSON data.”一个是包含JSON数据的对象,一个是可以读取JSON的流。而且这两种都必须遵守JSON的5类规范:UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE。

此外,其中值得注意的是options参数。Apple定义了3种参数给我们。分别是:

  • NSJSONReadingAllowFragments:,解析时将处理非NSArray和NSDictionary的格式。比如null,@”123”等。
  • NSJSONReadingMutableContainers:,解析时将生成NSMutableArray和NSMutableDictionary对象。
  • NSJSONReadingMutableLeaves:,解析时将生成NSMutableString对象。
  • 如果直接传nil的话,将默认生成NSArray和NSDictionary。

4 生成负载

4.1 JSON生成

还是NSJSONSerialization类。但方法换了2个:dataWithJSONObject:options:error和writeJSONObject:toStream:options:error。这两个方法的区别也一目了然了。

但是这里的options参数就只提供了一个NSJSONWritingPrettyPrinted。而且只是输出的时候增加可读性,不然就把全部数据整行输出。

此外。在创建JSON的时候NSJSONSerialization还提供了isValidJSONObject:这个类方法来验证对象是否能够转换成JSON(严谨的Apple~)。

满足JSON的条件如下:

  • 顶层对象是NSArray或NSDictionary。
  • 所有对象必须是NSString、NSNumber、NSArray、NSDictionary或NSNull。
  • 所有的NSDictionary键必须是NSString。
  • NSNumber不能为NaN或无穷大。
    参考自:NSJSONSerialization Class Reference from Apple Doc

4.2 XML生成

有一些第三方库支持写入XML。但iOS自带的API只有libxml一种。而且它是C写的。由于也不太常用。这里有一篇文章可以参考:iOS中用libxml写入数据


over