和 NSURLConnection 一样,NSURLSession 指的也不仅是同名类 NSURLSession,还包括一系列相互关联的类。NSURLSession 包括了与之前相同的组件,NSURLRequest 与 NSURLCache,但是把 NSURLConnection 替换成了 NSURLSession、NSURLSessionConfiguration 以及 NSURLSessionTask 的 3 个子类:NSURLSessionDataTask,NSURLSessionUploadTask,NSURLSessionDownloadTask。
NSURLSession 中另一大块就是 session task。它负责处理数据的加载以及文件和数据在客户端与服务端之间的上传和下载。NSURLSessionTask 与 NSURLConnection 最大的相似之处在于它也负责数据的加载,最大的不同之处在于所有的 task 共享其创造者 NSURLSession 这一公共委托者(common delegate)。
摘自https://imtangqi.com/2016/04/01/from-nsurlconnection-to-nsurlsession/
使用代码
NSURL *url = [NSURL URLWithString:@""];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15];
[NSURLConnection connectionWithRequest:request delegate:self];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
}];
在第二行中有个cachePolicy缓存策略,它是个枚举,无论用哪种都会有缓存
NSURLSession本身并不会请求数据,它就像一个容器,里面可以有许多请求,一个session你可以配置request等信息。每次使用都先创建一个session
需要NSURLSessionTask创建task,同一个 NSURLSession 可以创建多个 task,并且这些 task 之间的 cache 和 cookie 是共享的。
下面四种task类型:
NSURLSessionDataTask:使用这个 task 来调用 HTTP GET 方式请求,从服务器获取数据到内存。返回的数据格式是 NSData,可根据需要自行转换成 XML、JSON 等数据格式
NSURLSessionUploadTask:使用这个 task 来上传磁盘文件到 web 服务器,典型地通过 HTTP POST 或者 PUT 方式
NSURLSessionDownloadTask:使用这个 task 来从远程服务器下载文件到临时文件地址
NSURLSessionStreamTask:使用这个 task 来执行异步的读和写
当一个 NSURLSessionDataTask 完成时,它会带有相关联的数据,而一个 NSURLSessionDownloadTask 任务结束时,它会带回已下载文件的一个临时的文件路径。因为一般来说,服务端对于一个上传任务的响应也会有相关数据返回,所以 NSURLSessionUploadTask 继承自 NSURLSessionDataTask
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@""];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=1234&pwd=4321" dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
[task resume];
下面三个代理
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
NSLog(@"任务完成");
// 必须设置对响应进行允许处理才会执行后面两个操作。
completionHandler(NSURLSessionResponseAllow);
}
//收到服务器的数据(可能调用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 处理每次接收的数据
NSLog(@"%s",__func__);
}
// 3. 请求成功或者失败(如果失败,error有值)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// 请求完成,成功或者失败的处理
NSLog(@"SessionTask %s",__func__);
}
NSURLSessionConfiguration 对象用于对 NSURLSession 对象进行初始化。从指定可用网络,到 cookie,安全性,缓存策略,再到使用自定义协议,启动事件的设置,以及用于移动设备优化的几个新属性,你会发现使用 NSURLSessionConfiguration 可以找到几乎任何你想要进行配置的选项。其有三个类工厂方法:
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
默认模式(+defaultSessionConfiguration):返回一个标准的 configuration,工作模式类似于 NSURLConnection,可以使用缓存的 Cache,Cookie,证书(credential)
及时模式(+ephemeralSessionConfiguration): 临时 session 配置,与默认配置相比,这个配置不会使用缓存的 Cache,Cookie,证书,只会存在内存里,所以当程序退出时,所有的数据都会消失,这对于实现像秘密浏览这种功能来说是很理想的
后台模式(+backgroundSessionConfiguration):它会创建一个后台 session。后台 session 不同于常规的,普通的 session,它甚至可以在应用程序挂起,退出或者崩溃的情况下运行上传和下载任务。初始化时指定的标识符,被用于向任何可能在进程外恢复后台传输的守护进程(daemon)提供上下文
除了这三种预设的模式之外 NSURLSessionConfiguration 还可以进行很多的配置。 timeoutIntervalForRequest 和 timeoutIntervalForResource 可以控制网络操作的超时时间。 allowsCellularAccess 属性可以控制是否允许使用无线网络。HTTPAdditionalHeaders 可以指定 HTTP 请求头。感觉跟AFNetWorking封装的属性挺像的,都有。
一旦用配置好的 NSURLSessionConfiguration 初始化 NSURLSession 实例后,就不能修改这个 NSURLSession 相关的配置了。所以,一切的配置操作都放在初始化 NSURLSession 之前。
用例:
NSURLSession *session2 = [NSURLSession sessionWithConfiguration:[[NSURLSessionConfiguration alloc] init] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
一个NSURLConnection对象代表一个任务, 每个任务绑定一个configuration, 全部connection对象共享一个全局存储器(global storage).
一个NSURLSession对象绑定一个configuration, 一个session对象可以创建n个任务(NSURLSessionTask对象), 每个NSURLSession拥有一个私人存储器(private storage)
后台上传和下载:只需在创建 NSURLSession 的时候配置一个选项,就能得到后台网络的所有好处。这样可以延长电池寿命,并且还支持 UIKit 的多 task,在进程间使用相同的委托模型
能够暂停和恢复网络操作:使用 NSURLSession API 能够暂停,停止,恢复所有的网络任务,再也完全不需要子类化 NSOperation
可配置的容器:对于 NSURLSession 里面的 requests 来说,每个NSURLSession 都是可配置的容器。举个例来说,假如你需要设置 HTTP header 选项,你只用做一次,session 里面的每个 request 就会有同样的配置
提高认证处理:认证是在一个指定的连接基础上完成的。在使用 NSURLConnection 时,如果发出一个访问,会返回一个任意的 request。此时,你就不能确切的知道哪个 request 收到了访问。而在 NSURLSession 中,就能用代理处理认证
丰富的代理模式:在处理认证的时候,NSURLConnection 有一些基于异步的 block 方法,但是它的代理方法就不能处理认证,不管请求是成功或是失败。在 NSURLSession 中,可以混合使用代理和 block 方法处理认证
上传和下载通过文件系统:它鼓励将数据(文件内容)从元数据(URL 和 settings)中分离出来
https://www.jianshu.com/p/955307f6ddab
https://imtangqi.com/2016/04/01/from-nsurlconnection-to-nsurlsession/
https://objccn.io/issue-5-4/