iOS 网络请求及数据解析

来源:互联网 发布:小说辅助软件 编辑:程序博客网 时间:2024/06/05 14:53

URL:统一资源定位符,用来唯一表示一个资源地址;

基本格式:协议://主机地址/资源路径
协议:不同的协议,代表不同的资源查找方式,资源传递方式
主机地址:存放资源的主机的IP地址(域名)
路径:资源在主机中的具体位置
网络资源:http://www.xxx
本地资源:file:///users/apple/desktop/xxx

HTTP协议
超文本传输协议,规定客户端和服务器之间的数据传输方式,让客户端和服务器能有效地进行数据沟通;

NSURL:根据地址封装地址对象

NSURL * url = [NSURL URIWithString:@"http://..."];NSData *data = [NSData dataWithContentsOfURL:url];  // 获取数据流

NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信息有

一个NSURL对象
请求方法,请求头,请求体
请求超时(timeoutInterval)等等…

NSMutableURLRequest:NSURLRequest的子类,可以添加更改请求头

[request setValue:@"bytes=500-999" forHTTPHeaderField:@"Range"]; // 断点下载;

NSURLResponse:请求响应对象

response.allHeaderFields;  // 获取http请求响应头信息;response.expectedContentLength;  // 获取文件长度;

NSURLConnection

负责发送请求,建立客户端服务器的连接;
发送NSURLRequest的数据给服务器,并收集来自服务器的响应数据;

网络请求步骤:
1. 创建一个NSURL对象,设置请求路径;
2. 根据NSURL对象创建一个NSURLRequest对象,设置请求头和请求体,默认就是GET请求;
3. 使用NSURLConnection发送NSURLRequest;

发送网络请求有同步和异步两种方式

同步请求:

[conn sendSynchronousRequest:request returningResponse:nil error:ni]; // 同步请求,一直在等待服务器返回数据;

异步请求
<1>.直接发送请求

NSOperationQueue *queue = [[NSOperationQueue alloc] init];[conn sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response,NSData *data, NSError *error){ // 当请求成功或者遇到请求错误时调用;}];

第二个参数queue表示请求完成之后的代码块需要放置到哪个队列执行,如果手动新建一个queue,则会放到自己创建的queue中执行,如果想要更新ui,则需要传主线程的队列,通过[NSOperationQueue mainQueue]获取主队列;

<2>.通过代理来发送请求

+   NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];-   (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)immediately;// 如果immediately为NO,则需要再调用[conn start];  // 异步执行;// 实现代理对象4个常用方法-(void)connection: didFailWithError:  // 请求错误(失败)时调用(超时,断网,客户端错误);-(void)connection: didReceiveResponse:  // 当接收到服务器的响应就会被调用;-(void)connection: didReceiveData:  // 当接收到服务器的数据时调用(可能会多次调用);-(void)connectionDidFinishLoading:  // 服务器的数据接收完毕;

路径编码及请求参数设置

NSURL *url = [NSURL URLWithString:@"xxx"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 创建请求对象request.timeoutInterval = 5;  // 设置请求超时;request.HTTPMethod = @"POST";  // 设置POST请求;// equest.HTTPMethod = @"HEAD";  // 获取http请求头信息(发送同步或者异步请求都行,但最好是异步请求);[request setValue:@"ios" forHTTPHeaderField:@"User-Agent"];  // 设置请求头;// 设置请求体;NSString *param;request.HTTPBody=[param dataUsingEncoding:NSUTF8StringEncoding];

NSURL里面不能包含中文,需要进行转码;

NSString *urlstr;urlstr = [urlstr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURLCache

硬盘缓存的位置:沙盒/Library/Caches

NSURLCache *cache = [NSURLCache sharedURLCache];  // 获取全局缓存对象-(void)setMemoryCapacity:(NSUInteger)memoryCapacity;  // 设置内存缓存最大容量(默认为512kb)-(void)setDiskCapacity:(NSUInteger)diskCapacity;  // 设置硬盘缓存最大空间(默认10M)

缓存策略:

NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议,也就是需要设置request的cookie等请求头)NSURLRequestReturnCacheDataElseLoad //先加载缓存,如果没有则再去请求request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // 设置request的缓存策略

缓存操作:

-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; // 获取某个请求的缓存-(void)removeCachedResponseForRequest:(NSURLRequest *)request; // 清除某个请求的缓存-(void)removeAllCachedResponses; // 清除所有缓存

数据解析

Json解析(Json的MIMETYPE为application/json)

NSString *path = [[NSBundle mainBundle] pathForResource:@"data.json" ofType:nil];NSData *data = [NSData dataWithContentsOfFile:path]; // 根据文件路径加载json文件到NSData中;// 将加载进来的NSData数据转换为OC中的对象;id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:NULL];[self setValueForKeysWithDictionary:dict];

NSJSONSerialization 常用方法:

JSON数据->OC对象

+(id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error

OC对象->JSON数据

+(NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error

XML解析
DOM:一次性将整个xml文档加载进内存,比较适合解析小文件;
SAX:从根开始,按顺序一个元素一个元素向下解析,比较适合解析大文件;

SAX解析

NSData *data;NSXMLParser * parser = [[NSXMLParse alloc] initWithData:data];parser.delegate = self;[parser parse]; // 开始解析,解析过程是同步的,解析完成后再执行之后的方法;

DOM解析

GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; // 加载文档CDataXMLElement *root = doc.rootElement; // 获取根元素NSArray *arr = [root elementsForName:@"videos"]; // 获取元素集合for(CDataXMLElement *ele in arr){ // 解析元素    [ele attributeForName:@"id"].stringValue; // 获取节点属性值;}

iOS9 新特性

The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.Google后查证,iOS9引入了新特性App Transport Security (ATS)。详情:App Transport Security (ATS)

新特性要求App内访问的网络必须使用HTTPS协议。
但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。
解决办法:

在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES。

第三方框架

ASI
依赖于三个框架

libz.1.2.5.dylibMobileCoreServices.frameworkSystemConfiguration.framework

ASIHTTPRequest
继承自NSOperation,所以也就可以将多个ASIHTTPRequest添加到NSOperationQueue中,同时管理多个请求,也可以设置请求之间的依赖;

[request clearDelegatesAndCancel];  // 当控制器被销毁的时候,取消请求;[request setSceondsToCache:60 * 60 * 24 * 7];  // 缓存7天;[request didUseCachedResponse];  // 判断数据是否从缓存读取;

​1.GET请求

ASIHTTPRequest *reqeust = [ASIHTTPRequest requestWithURL:url];

2.POST请求

ASIFormDataRequest *reqeust = [ASIFormDataRequest requestWithURL:url];[request setPostValue:@"key1" forKey:@"value1"]; // 非文件参数

3.文件下载

request.downloadDestinationPaht = filePath; // 文件下载路径request.downloadProgreddDelegate = progressView; // 下载代理,监听下载进度request.allowResumeForFileDownloads = YES; // 支持断点下载

4.文件上传

[request setFile:file forKey:@"file"]; // 添加文件参数(file:要上传的文件的路径)[request setFile:file withFileName:@"xx.txt" andContentType:@"text/plain"]; // xx.png image/pngrequest.uploadProgressDelegate = progressView; // 上传代理(监听上传进度)

5.监听请求的过程
<1>. 代理方法

request.delegate = self;  // 遵守协议ASIHTTPRequestDelegate// 实现代理方法-(void)requestStarted:(ASIHTTPRequest *)request;-(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;-(void)requestFinished(ASIHTTPRequest *)request;-(void)requestFailed:(ASIHTTPRequest *)request;

<2>. SEL

request.delegate = self;  // 设置代理[request setDidStartSelector:@selector(start)];  // 开始发送请求的时候调用start方法

<3>. block

[request setStartedBlock:^{}];[request setDataReceivedBlock:^(NSData *data){}];[request setCompletionBlock:^{}];[request setFailedBlock:^{}];

6.通过requst对象获取服务器的响应
<1>. 获取响应头信息

@property (atomic, retain) NSDictionary *responseHeaders;

2> 获取响应体

-(NSData *)responseData;  // 直接返回服务器的二进制数据-(NSString *)responseString;  // 将二进制数据转换成字符串(debug)

7.缓存

// 1.获取全局缓存对象(缓存的存储路径)ASIDownloadCache *cache = [ASIDownloadCache sharedCache];// 1.1设置默认折缓存加载策略cache.defaultCachePolicy = ASIDoNotReadFromCacheCachePolicy;// 2.设置请求对象的缓存对象request.downloadCache = cache;// 3.设置请求对象的缓存加载策略request.cachePolicy = ASIOnlyLoadIfNotCachedCachePolicy;// 4.设置请求对象的缓存存储策略request.cacheStoragePolicy = ASICachePermanentlyCacheStoragePolicy;// 5.优先级request.cachePolicy > cache.defaultCachePolicy;

AFN
1.GET/POST

// 1.获取请求管理者AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; // 2.封装请求参数NSMutableDictionary *params = [NSMutableDictionary dictionary];params[@"key1"] = @"value1";// 3.发送GET请求[mgr GET:@"http://..." parameters:params success:^(AFHTTPRequestOperation *operation ,id responseObject){} failure:^(AFHTTPRequestOperation *operation, NSError *error){}];// 4.发送POST请求,只需要把3中的GET换成POST即可

2.文件上传

// 1.获取请求管理者AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];// 2.封装请求参数#只能放非文件参数NSMutableDictionary *params = [NSMutableDictionary dictionary];params[@"key1"] = @"value1";// 3.上传文件[mgr POST:@"http://..." parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData){ // 在block方法中添加文件参数  NSData *data = [NSData dataWithContentsOfFile:file]; [formData appendPartWithFileData:data name:@"file" fileName:@"12.txt" mimeType:@"text/plain"]; } success:^(AFHTTPRequestOperation *operation ,id responseObject){} failure:^(AFHTTPRequestOperation *operation, NSError *error){}];

3.网络监控

AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status){}];[mgr startMonitorint];  // 开始监控

ASI和AFN区别
1.性能

ASI基于底层CFNetwork
AFN基于NSURLConnection
运行性能:ASI > AFN

2.处理服务器数据

<1>. AFN:根据服务器返回的数据,自动解析
JSON数据自动转换为NSDictionary或者NSArray
XML数据自动转换为NSXMLParser
<2>. ASI:直接返回NSData二进制数据

3.处理请求的过程

AFN:success和failure两个block
ASI:有三种方法处理请求过程(代理方法\SEL\block)

4.特点
ASI:

缓存
下载和上传
* 监听请求进度
* 实现断点下载(ASI没有断点上传功能,断点上传需要使用socket)
提供了扩展接口(比如数据压缩)
ASIDataCompressor.h
ASIDataDecompressor.h
ASIHttpRequest继承自NSOperation
* 能用队列统一管理所有请求
* 请求之间能够依赖
ASINetworkQueue
* 统一管理所有请求
* 多个下载\上传 –> ASINetworkQueue
* 监听多个请求的总进度(开始/失败/完毕)
* shouldCancelAllRequestOnFailure // 返回YES: 队列中的某个请求失败后,其它所有请求都取消;

AFN默认的数据解析器是JSON数据解析器,而默认的json数据解析器只支持三种服务器返回的数据类型(Content-type);
分别是:application/json,text/json,text/javascript,我们可以自己在集合中再添加一种数据类型;

AFHTTPRequestOperationManager *mgr;mgr.responseSerializer.acceptableContentTypes;  // 解析器支持的数据集合;
0 0
原创粉丝点击