iOS开发之网络编程:常用网络内部类(NSURLSession)

一、NSURLConnection

我们在前面几节介绍过NSURLConnection发送请求的几种方法,除了同步请求直接获取data,异步请求的以block回调的形式来获取data,NSURLConnection还可以采用代理方法来获取data,方法有点类似XML的sax解析。请求的创建和以前一样,这一节我采用的是Post请求。

 
 
  1. // 1.获取请求网址
  2. NSURL *url = [NSURL URLWithString:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?"];
  3. // 2.封装请求
  4. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; // post
  5. // 设置请求方式
  6. [request setHTTPMethod:@"POST"];
  7. // 设置请求体(会把请求的数据转成data,达到用户信息保密的目的)
  8. NSData *data = [@"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];
  9. [request setHTTPBody:data];
  10. [NSURLConnection connectionWithRequest:request delegate:self];

既然设置了代理,就要遵守对应的协议。

 
 
  1. <NSURLConnectionDelegate, NSURLConnectionDataDelegate>

NSURLConnectionDelegate的代理方法,主要是用来判断连接状态,处理各类连接情况,常用的就是连接失败。

 
 
  1. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
  2. {
  3. //  获取到对应错误信息。
  4. if(error)
  5. {
  6. NSLog(@"%@", [error localizedDescription]);
  7. }
  8. }

NSURLConnectionDataDelegate则主要是获取服务器响应,接收数据。

 
 
  1. // 收到服务器响应
  2. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  3. {
  4. NSLog(@"收到服务器响应");
  5. }
  6.  
  7. // 可能多次调用,可以多次拼接获取的数据
  8. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  9. {
  10. [self.myData appendData:data];
  11. NSLog(@"收到数据");
  12. }
  13.  
  14. // 完成数据接收
  15. - (void)connectionDidFinishLoading:(NSURLConnection *)connection
  16. {
  17. NSError *error = nil;
  18. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.myData options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];
  19. if(error)
  20. {
  21. NSLog(@"%@", [error localizedDescription]);
  22. }
  23. NSLog(@"%@", dic);
  24. }

由于这里面需要拼接数据,所以需要一个容器来保存多次接收的数据,在前面申明一个NSMutableData类型的属性。

 
 
  1. @property (nonatomic, strong) NSMutableData *myData;
 
 
  1. // 懒加载
  2. - (NSMutableData *)myData
  3. {
  4. if(_myData == nil)
  5. {
  6. self.myData = [NSMutableData data];
  7. }
  8. return _myData;
  9. }

到这里,一套流程基本完成了。发送请求时候,如果发送出错,调用didFailWithError:方法来输出错误信息。如果没有错误,收到服务器响应,会调用didReceiveResponse:方法。然后从服务器返回数据,通过didReceiveData:方法。如果数据量比较大,这个方法会多次调用,所以需要拼接获取到得数据。最后数据接收完成,会调用connectionDidFinishLoading:方法,这里面可以做数据解析。

 二、NSURLSession

在WWDC 2013中,Apple的团队对NSURLConnection进行了重构,并推出了NSURLSession作为替代。

NSURLSession也是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不同之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。

下面咱们来简单看一下NSURLSession请求数据的流程。前面创建Request的方式不变。

 
 
  1. // 1.获取请求网址
  2. NSURL *url = [NSURL URLWithString:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?"];
  3. // 2.封装请求
  4. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; // post
  5. // 设置请求方式
  6. [request setHTTPMethod:@"POST"];
  7. // 设置请求体(会把请求的数据转成data,达到用户信息保密的目的)
  8. NSData *data = [@"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];
  9. [request setHTTPBody:data];
  10.  
  11. // 创建NSURLSession,设置代理,就要遵守协议,配置为默认配置,代理方法执行在主线程。
  12. NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
  13. NSURLSessionDataTask *task = [session dataTaskWithRequest:request
  14. completionHandler:
  15. ^(NSData *data, NSURLResponse *response, NSError *error) {
  16. // 获取数据
  17. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
  18. NSLog(@"%@", dic);
  19. }];
  20. [task resume];

代理方法:

 
 
  1. // 在协议的方法中可以完成各种各样的回调动作,如身份验证、完成任务后的动作、错误处理和后台任务完成的动作等。委托方法指定在NSURLSession中一定数量的字节传输使用int64_t类型的参数。
  2. - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error;
  3.  
  4. - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
  5. completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler;
  6.  
  7. - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session NS_AVAILABLE_IOS(7_0);

还有2种创建NSURLSession的方法:

 
 
  1. // NSURLSession *session = [NSURLSession sharedSession];
  2. // NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

 三、总结

其实这两个类的使用流程大差不差,那么苹果为什么要重构一个NSURLSession来替换NSURLConnection呢?

与NSURLConnection相比,NSURLSession最直接的改善就是提供了配置每个会话的缓存,协议,cookie和证书政策(credential policies),甚至跨应用程序共享它们的能力。这使得框架的网络基础架构和部分应用程序独立工作,而不会互相干扰。每一个NSURLSession对象都是根据一个NSURLSessionConfiguration初始化的,该NSURLSessionConfiguration指定了上面提到的政策,以及一系列为了提高移动设备性能而专门添加的新选项。

NSURLSession的另一重要组成部分是会话任务,它负责处理数据的加载,以及客户端与服务器之间的文件和数据的上传下载服务。NSURLSessionTask与NSURLConnection是及其相似的,因为它负责加载数据,而主要的区别在于,任务共享它们父类NSURLSession的共同委托(common delegate)。

简而言之,就是在处理多任务上传下载,频繁切换前台后台的时候,NSURLSession明显是有很大的优势。如果只是像咱们上面这样简单的获取一个JSon数据,其实是看不出来什么差别的,反而还会觉得NSURLSession比较麻烦,毕竟先入为主。咱们教程也是立志于简单使用,如果大家对这些有深入了解的兴趣,不妨可以按照网上一些思路,去自己探索一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值