NSURLSession
iOS9之前在做网络连接的时候,我们使用的时NSURLConnection,但是iOS9之后NSURLConnection宣布被弃用了,在2013年的WWDC大会上,苹果就已经设计出NSURLConnection的继任者NSURLSession,他使用起来比NSURLConnection更加简单,更加强大。
接下里我们就来看一下NSURLSession的优点:
1.后台上传和下载:只需在创建NSURLSession的时候配置一个选项,就能得到后台网络的所有好处。这样可以延长电池寿命,并且还支持UIKit的多task,在进程间使用相同的委托模型。
2.能够暂停和恢复网络操作:使用NSURLSession API能够暂停,停止,恢复所有的网络任务,再也完全不需要子类化NSOperation.
3.可配置的容器:对于NSURLSession里面的requests来说,每个NSURLSession都是可配置的容器。举个例来说,假如你需要设置HTTP header选项,你只用做一次,session里面的每个request就会有同样的配置。
4.提高认证处理:认证是在一个指定的连接基础上完成的。在使用NSURLConnection时,如果发出一个访问,会返回一个任意的request。此时,你就不能确切的知道哪个request收到了访问。而在NSURLSession中,就能用代理处理认证。
5.丰富的代理模式:在处理认证的时候,NSURLConnection有一些基于异步的block方法,但是它的代理方法就不能处理认证,不管请求是成功或是失败。在NSURLSession中,可以混合使用代理和block方法处理认证。
NSURLSession之所有能这么强大,和与他配套使用的类是分不开的,与他结合使用的类有NSURLSessionConfiguration 和 NSURLSessionTask;
NSURLSessionConfiguration 有三个方法可以创建:
1.defaultSessionConfiguration-使用全局的cache,cookie和credential storage objects来创建configuration对象。
2.ephemeralSessionConfiguration –这个configuration用于“private” sessions,还有对于cache, cookie, or credential storage objects的非永久存储。
3.backgroundSessionConfiguration –做远程push通知或是应用程序挂起的时候就要用到这个configuration。
创建NSURLSession的两种方式:
第一种:需要手动设置NSURLSession对象的属性
先创建NSURLSessionConfiguration,使用它配置NSURLSession对象的属性:如下:
NSURLSessionConfiguration *sessinConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 限制了网络只能是wifi
sessinConfiguration.allowsCellularAccess = NO;
// 设置了所有的请求只接受JSON数据
[sessinConfiguration setHTTPAdditionalHeaders:@{@"Accept" : @"application/json"}];
// 配置网络超时
sessinConfiguration.timeoutIntervalForRequest = 30.0;
sessinConfiguration.timeoutIntervalForResource = 60.0;
// 限制了一个主机只有一个网络连接
sessinConfiguration.HTTPMaximumConnectionsPerHost = 1;
// 创建session对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessinConfiguration];
第二种:使用单例的方式创建NSURLSession对象,使用默认的属性设置
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask:是一个抽象类,是任务类的基类,包含三个子类
NSURLSessionDataTask: 数据请求任务类
NSURLSessionDownloadTask: 下载任务
NSURLSessionUploadTask:上传任务
NSURLSeesionDataTask 使用举例:
1.创建网络会话对象
NSURLSession *session =[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
2、创建数据请求任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://mobile.ximalaya.com/m/explore_album_list?category_name=all&condition=hot&device=android&page=1&per_page=20&status=0&tag_name=%E5%8D%81%E4%BA%8C%E6%98%9F%E5%BA%A7"]]];
3、开启任务
[task resume];
在这里需要主要的是,NSURLSessionTask任务默认是挂起的,创建好任务之后要把任务重新变得活跃起来。
NSURLSessionDownloadTask: 下载任务 GET请求
// 配置session的属性
NSURLSessionConfiguration *sessinConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSString *urlString = @"http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
request.HTTPMethod = @"GET";
// 创建session对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessinConfiguration];
// 下载任务
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
}];
// 恢复任务
[task resume];
// 在这里需要注意的是有
1.默认NSURLSessionTask的任务是丢到子线程完成,也就相当于NSURLConnection中的异步连接,所以在数据请求完之后,刷新UI的操作的要重新推回主线程才可以。
2. 需要注意的就是将下载的到tmp文件夹的文件移动到需要的目录
3. location是沙盒中tmp文件夹下临时的url,文件下载后会存到这个位置,由于tmp中的文件随时都可以被删除,所以我们需要把下载的文件移动到需要的其他文件中保存起来
4. response.suggestedFilename是从响应中取出文件在服务器上存储路径的最后部分,如http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg,则suggestedFilename就是2010113143922418.jpg
NSURLSessionUploadTask:上传任务 可以上传NData类型数据,也可以直接上传文件,在这里我们只说使用的方法,需要注意的是上传使用的是POST请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = body;
// 方法中第二个参数就是我们要上传的二进制流数据
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}
// 方法中第二参数是我们要上传的文件路径
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromFile:filePath completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}
NSURLSession还有很多的使用方法,NSURLSession的也可设置代理来完成每个任务,需要注意的是代理属性是只读的,必须是要相关的方法才能设置代理sessionWithConfiguration: delegate: delegateQueue:这个方法,代理的相关方法和NSURLConnection的协议方法都很相似,在理我们就不一一介绍了。