NSURLSession使用

1.NSURLSession诞生于2013年,但其在前几年一直生活在NSURLConnection的阴影下,直到iOS9的出现,NSURLConnection被官方宣布弃用,才正式走向舞台。

NSURLSession老程序员原来很少用

NSURLConnection新程序员甚至不知道

还有些程序员只知道AFN

2.相关类

a、NSURLSession

b、NSURLSessionConfiguration

c、NSURLSessionTask

3.NSURLSession的使用

使用NSURLSession,共分两步:

  • 第一步 通过NSURLSession的实例创建task
  • 第二步 执行task

task是什么东西?

NSURLSessionTask可以简单理解为任务:如数据请求任务,下载任务,上传任务and so on.我们使用的是他的子类们:

  • NSURLSessionTask(抽象类)
    • NSURLSessionDataTask(数据任务类)
      • NSURLSessionUploadTask(上传任务类)
    • NSURLSessionDownloadTask(下载任务类)

NSURLSessionDataTask

字面上看是和数据相关的任务,但其实dataTask完全可以胜任downloadTask和uploadTask的工作.这也是我们使用最多的task种类.

简单GET请求

如果请求的数据比较简单,也不需要对返回的数据做一些复杂的操作.那么我们可以使用带block

// 快捷方式获得session对象

NSURLSession *session = [NSURLSession sharedSession];

NSURL url = [NSURL URLWithString:@"http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode=1330000&userID="];

// 通过URL初始化task,在block内部可以直接对返回的数据进行处理

NSURLSessionTask task = [session dataTaskWithURL:url

completionHandler:^(NSData data, NSURLResponse response, NSError error) {

NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);

}];

// 启动任务

[task resume];

注意:

  • 所有类型的task都要调用resume方法才会开始进行请求.

简单POST请求

POST和GET的区别就在于request,所以使用session的POST请求和GET过程是一样的,区别就在于对request的处理.

NSURL url = [NSURL URLWithString:@"http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo"];

NSMutableURLRequest request = [NSMutableURLRequest requestWithURL:url];

request.HTTPMethod = @"POST";

request.HTTPBody = [@"mobileCode=1330000&userID=" dataUsingEncoding:NSUTF8StringEncoding];

NSURLSession session = [NSURLSession sharedSession];

// 由于要先对request先行处理,我们通过request初始化task

NSURLSessionTask task = [session dataTaskWithRequest:request

completionHandler:^(NSData data, NSURLResponse response, NSError *error) {

NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);

}];

[task resume];

NSURLSessionDataDelegate代理方法

NSURLSession提供了block方式处理返回数据的简便方式,但如果想要在接收数据过程中做进一步的处理,仍然可以调用相关的协议方法.NSURLSession的代理方法和NSURLConnection有些类似,都是分为接收响 应、接收数据、请求完成几个阶段.

// 使用代理方法需要设置代理,但是session的delegate属性是只读的,要想设置代理只能通过这种方式创建session

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]

delegate:self

delegateQueue:[[NSOperationQueue alloc] init]];

// 创建任务(因为要使用代理方法,就不需要block方式的初始化了)

NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode=1330000&userID="]]];

// 启动任务

[task resume];

//对应的代理方法如下:

// 1.接收到服务器的响应

- (void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {

// 允许处理服务器的响应,才会继续接收服务器返回的数据

completionHandler(NSURLSessionResponseAllow);

}

// 2.接收到服务器的数据(可能调用多次)

- (void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveData:(NSData *)data {

// 处理每次接收的数据

}

// 3.请求成功或者失败(如果失败,error有值)

- (void)URLSession:(NSURLSession )session task:(NSURLSessionTask )task didCompleteWithError:(NSError *)error {

// 请求完成,成功或者失败的处理

}

注意:

关键点在代码注释里面都有提及,重要的地方再强调一下:

  • 如果要使用代理方法,需要设置代理,但从NSURLSession的头文件发现session的delegate属性是只读的.因此设置代理要通过session的初始化方法赋值:sessionWithConfiguration:delegate:delegateQueue:其中:
    • configuration参数(文章开始提到的)需要传递一个配置,我们暂且使用默认的配置[NSURLSessionConfiguration defaultSessionConfiguration]就好;
    • delegateQueue参数表示协议方法将会在哪个队列(NSOperationQueue)里面执行.
  • NSURLSession在接收到响应的时候要先对响应做允许处理:completionHandler(NSURLSessionResponseAllow);,才会继续接收服务器返回的数据,进入后面的代理方法.值得一提的是,如果在接收响应的时候需要对返回的参数进行处理(如获取响应头信息等),那么这些处理应该放在前面允许操作的前面.

NSURLSessionDownloadTask

文件下载可以使用NSURLSessionDownloadTask这个子类.

简单下载

NSURLSessionDownloadTask同样提供了通过NSURL和NSURLRequest两种方式来初始化并通过block进行回调的方法.下面以NSURL初始化为例:

NSURLSession session = [NSURLSession sharedSession];

NSURL url = [NSURL URLWithString:@"http://bvideo.spriteapp.cn/video/2016/0601/574dddfa521ec_wpd.mp4"] ;

NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

// location是沙盒中tmp文件夹下的一个临时url,文件下载后会存到这个位置,由于tmp中的文件随时可能被删除,所以我们需要自己需要把下载的文件挪到需要的地方

NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

// 剪切文件

[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];

}];

// 启动任务

[task resume];

注意:

  • 需要注意的就是需要将下载到tmp文件夹的文件转移到需要的目录.原因在代码中已经贴出.
  • response.suggestedFilename是从相应中取出文件在服务器上存储路径的最后部分,如数据在服务器的url为http://bvideo.spriteapp.cn/video/2016/0601/574dddfa521ec_wpd.mp4, 那么其suggestedFilename就是574dddfa521ec_wpd.mp4.

断点下载

NSURLSessionDownloadTask提供了与断点下载相关的几个方法:

// 使用这种方式取消下载可以得到将来用来恢复的数据,保存起来

[self.task cancelByProducingResumeData:^(NSData *resumeData) {

self.resumeData = resumeData;

}];

// 由于下载失败导致的下载中断会进入此协议方法,也可以得到用来恢复的数据

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

{

// 保存恢复数据

self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];

}

// 恢复下载时接过保存的恢复数据

self.task = [self.session downloadTaskWithResumeData:self.resumeData];

// 启动任务

[self.task resume];

NSURLSessionUploadTask

在NSURLSession中,文件上传方式主要有以下两种:

NSURLSessionUploadTask *task =

[[NSURLSession sharedSession] uploadTaskWithRequest:request

fromFile:fileName

completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

}];

[self.session uploadTaskWithRequest:request

fromData:body

completionHandler:^(NSData data, NSURLResponse response, NSError *error) {

NSLog(@"-------%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);

}];

处于安全性考虑,通常我们会使用POST方式进行文件上传,所以较多使用第二种方式.

其他

此外,task们自身有都拥有下面几个方法

- (void)suspend;

- (void)resume;

- (void)cancel;

suspend可以让当前的任务暂停 resume方法不仅可以启动任务,还可以唤醒suspend状态的任务 cancel方法可以取消当前的任务,你也可以向处于suspend状态的任务发送cancel消息,任务如果被取消便不能再恢复到之前的状态.

NSURLSessionConfiguration

以下就是session的配置信息.如:

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

// 超时时间

config.timeoutIntervalForRequest = 10;

// 是否允许使用蜂窝网络(后台传输不适用)

config.allowsCellularAccess = YES;

+ (NSURLSessionConfiguration *)defaultSessionConfiguration;

+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;

+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier

表示了NSURLSession几种不同的工作模式. 默认的配置会将缓存存储在磁盘上,第二种瞬时会话模式不会创建持久性存储的缓存,第三种后台会话模式允许程序在后台进行上传下载工作.

NSURLSession使用(整理版)的更多相关文章

  1. 一个项目涉及到的50个Sql语句(整理版)

    /* 标题:一个项目涉及到的50个Sql语句(整理版) 说明:以下五十个语句都按照测试数据进行过测试,最好每次只单独运行一个语句. */ --1.学生表Student(S,Sname,Sage,Sse ...

  2. 任正非讲话稿 PDF整理版

    任正非讲话稿 PDF整理版 任正非思想之路 这里收录了任正非讲话稿400余篇,从1994年到2018年,从深圳.中国到东南亚.非洲.欧洲.美洲,从研发.市场.服务到财经.人力资源.战略.内控与公共关系 ...

  3. 【转帖】Flink 核心技术浅析(整理版)

    Flink 核心技术浅析(整理版) https://www.cnblogs.com/swordfall/p/10612404.html 分类: Flink undefined 1. Flink简介 A ...

  4. 菜农群课笔记之ICP与ISP----20110412(整理版)

    耗时一上午时间对HOT大叔昨晚的群课内容进行温故并整理,现将其上传,若想看直播可到下面链接处下载:http://bbs.21ic.com/icview-229746-1-1.html        成 ...

  5. Java并发编程面试题 Top 50 整理版

    本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...

  6. Java虚拟机—垃圾收集器(整理版)

    1.概述 如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有规定,因此不同的厂商.不同版本的虚拟机所提供的垃圾收集器都可能会有很 ...

  7. Java虚拟机—垃圾回收算法(整理版)

    1.概述 由于垃圾收集算法的实现涉及大量的程序细节.因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程.主要涉及的算法有标记-清除算法.复制算法.标记-整理算法.分代收集算法. 2 ...

  8. App测试流程及测试点(个人整理版)

    1 APP测试基本流程 1.1流程图 1.2测试周期测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日),根据项目情况以及版本质量可适当缩短或延长测试时间.正式测试前先向主 ...

  9. Hadoop每日一讨论整理版

    这是我在几个QQ群发起的Hadoop每日一讨论小活动,每天中午2点左右发出一个关于Hadoop的知识片段,在此做一个整理. [每日一讨论]之计算框架(2013-5-21) 就计算框架而言,Hadoop ...

随机推荐

  1. CSP-S 95 (sb lsc yy赛)

    sb lsc 终于改完题了!(心力交悴.png)

  2. Flink中异步AsyncIO的实现 (源码分析)

    先上张图整体了解Flink中的异步io 阿里贡献给flink的,优点就不说了嘛,官网上都有,就是写库不会柱塞性能更好 然后来看一下, Flink 中异步io主要分为两种 一种是有序Ordered 一种 ...

  3. MySQL每个分类的前几条记录

    MySQL 获取所有分类和每个分类的前几条记录 比如有文章表 Article(Id,Category,InsertDate) 现在要用SQL找出每种类型中时间最新的前N个数据组成的集合 SELECT ...

  4. Spring Security登录验证流程源码解析

    一.登录认证基于过滤器链 Spring Security的登录验证流程核心就是过滤器链.当一个请求到达时按照过滤器链的顺序依次进行处理,通过所有过滤器链的验证,就可以访问API接口了. SpringS ...

  5. Nginx使用反向代理实现负载均衡

    Nginx使用反向代理实现负载均衡 yls 2019-9-20 简介 基于docker容器以及docker-compose,所以需要自学docker在linux环境的基本使用 使用两个tomcat作为 ...

  6. 在linux (centos)上使用puppeteer实现网页截图

    1.安装nodejs和npm # 下载解压 wget -c https://nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz tar -xvf n ...

  7. nyoj 65-另一种阶乘问题 (Java 高精度)

    65-另一种阶乘问题 内存限制:64MB 时间限制:3000ms 特判: No 通过数:16 提交数:18 难度:1 题目描述: 大家都知道阶乘这个概念,举个简单的例子:5!=1*2*3*4*5.现在 ...

  8. 【原创】(十一)Linux内存管理slub分配器

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  9. Python第五天 列表练习 元组类型 字典类型 小购物车练习

    # 反转 reverse# l=['lili','asdf','qwer','80000']# l.reverse()# print(l) # ['80000', 'qwer', 'asdf', 'l ...

  10. javescript 的 对象

    一,定义:对象是JavaScript的一个基本数据类型,是一种复合值,它将很多值(原始值或者其他对象)聚合在一起,可通过名字(name/作为属性名)访问这些值.即属性的无序集合. 关键是name属性名 ...