所谓负载指的是数据体,表示将要处理的传输意图。
Web Service协议与风格
协议指的是在与其他系统交换结构化信息时所要遵循的一套格式、过程、规则。
简单对象访问协议
简单对象访问协议(SOAP)是个轻量级协议,用于通过XML实现系统间的结构化数据交换。
在移动环境下的变更将会非常困难。
表述性状态转移
REST,是一种架构设计风格,可以应用到Web Service。
选择一种方式
负载
负载值得是在服务的请求响应事务中交换的数据。
负载数据格式简介
1、XML

是一种标记性语言,用于编码和组织数据。SOAP协议也通过XML来交换结构化数据。
XML文档包含标记和内容。
标记由标签、属性、元素构成。
标签有3种类型:起始标签、结束标签、空元素标签。
属性指的是起始标签、空元素标签中的键值对。
<person>
<firstName> Nathan </firstName>
<lastName> Jones </lastName>
<emailAddress primary = 'true'> [email protected] </emailAddress>
<noContact medium = 'email'>
</person>
2、JSON
是一种用于交换结构化信息的轻量级数据格式。
{
"person" :
{
"firstName" : "Nathan",
"lastName" : "Jones",
"email" :
{
"emailAddress" : "[email protected]",
"primary" : true
},
"noConract" : "email"
}
}
3、HTML
是一种标记语言,用于组织网页上的数据,这样浏览器就可以解析页面了。
解析响应负载
1、XML
有两种解析方式:
SAX会顺序解析XML文档中的元素,一次处理一个元素;
DOM会将整个XML文档以可遍历的节点树的形式读取到内存中。
iOS自带了两种原生XML解析器,分别是NSXMLParser、libxml。
NSXMLParser是SAX解析器,libxml是开源c语言API,支持SAX与DOM解析。
还有很多第三方的XML库可供使用:
- TBXML
- TouchXML
- KissXML
- GDataXML
预期的XML文档大小是个重要的考虑因素。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Post : NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *postDescription;
@property (nonatomic, copy) NSString *cotent;
@property (nonatomic, copy) NSString *author;
@property (nonatomic, copy) NSString *section;
@property (nonatomic, copy) NSString *contentURL;
@property (nonatomic, strong) NSDate *pubDate;
@property (nonatomic, strong) NSMutableArray *keywords;
@property (nonatomic, strong) NSMutableArray *tweets;
@property (nonatomic, assign) BOOL contentFetched;
@property (nonatomic, assign) BOOL tweetsLoading;
-(NSDictionary *)dictonaryRepresentation;
@end
NS_ASSUME_NONNULL_END
#import <Foundation/Foundation.h>
@protocol TopStoriesParserDelegate <NSObject>
@required
-(void)topStoriesParsedWithResult:(NSMutableArray *_Nullable)posts;
@end
NS_ASSUME_NONNULL_BEGIN
@interface TopStoriesParser : NSObject
@property (nonatomic, strong) NSData *feedData;
@property (nonatomic, strong) NSMutableArray *posts;
@property (nonatomic, weak) id<TopStoriesParserDelegate> delegate;
-(id)initWithFeedData:(NSData *)data;
-(void)parseTopStoriesFeed;
@end
NS_ASSUME_NONNULL_END
#import "TopStoriesParser.h"
#import "Post.h"
@interface TopStoriesParser ()
<NSXMLParserDelegate>
{
Post *post;
NSMutableString *currentValue;
BOOL parsingItem;
}
@end
@implementation TopStoriesParser
-(id)initWithFeedData:(NSData *)data
{
self = [super init];
if (self != nil)
{
self.feedData = data;
}
return self;
}
-(void)parseTopStoriesFeed
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:_feedData];
parser.delegate = self;
[parser parse];
}
/**
NSXMLParserDelegate 解析器开始解析
*/
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
_posts = [[NSMutableArray alloc] init];
}
/**
当解析器到达文档末尾*/
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
if ([_delegate respondsToSelector:@selector(topStoriesParsedWithResult:)])
{
[_delegate topStoriesParsedWithResult:_posts];
}
}
/**
开始处理新元素时
*/
-(void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
if ([elementName isEqualToString:@"item"])
{
post = [[Post alloc] init];
parsingItem = YES;
}
}
/**
从元素中读取内容
*/
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSString *tmpValue = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (currentValue == nil)
{
currentValue = [[NSMutableString alloc] initWithString:tmpValue];
}
else
{
[currentValue appendString:tmpValue];
}
}
/**
元素关闭时
*/
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"item"])
{
[_posts addObject:post];
post = nil;
parsingItem = NO;
}
if (parsingItem == YES)
{
if ([elementName isEqualToString:@"title"])
{
post.title = currentValue;
}
else if ([elementName isEqualToString:@"description"])
{
post.postDescription = currentValue;
}
else if ([elementName isEqualToString:@"pubDate"])
{
post.pubDate = [utils publicationdateFromString:currentValue];
}
else if ([elementName isEqualToString:@"feedburner:origLink"])
{
post.contentURL = currentValue;
}
}
currentValue = nil;
}
@end
2、HTML
3、JSON
从iOS5开始,Apple通过NSJSONSerialization类提供了原生的JSON解析支持。
通过两个方法来解析JSON数据:
JSONObjectWithData:options:error:
JSONObjectWithStream:options:error:
NSError *error = nil;
NSDictionary *searchResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
生成请求负载
1、JSON
2、XML
小结
将数据发送给移动设备的最佳架构是REST。对于iOS应用来说,最佳的数据交换格式是JSON。