NSURLSession的使用
看SDWebimage的源码,看到下载图片,用的是这个类。才发觉在开发中,AFN和SDWebimage把平时和网络打交道的事情干完了,导致这个类没怎么用过。现在来简单了解一下。
一、简单使用
加载一个图片
根据session加载图片.png
直接看代码:
self.imgv = [[UIImageView alloc] initWithFrame:CGRectMake(30, 100, 150, 150)];
[self.view addSubview:self.imgv];
self.session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
self.imgv.image = image;
});
}];
[task resume];
其中,一个imageview,根据一个url显示图片。
1、新建一个NSURLSession,可以用sharedSession快速创建。
2、再新建NSURLSessionDataTask对象,
3、最后resume启动。
总共三步,就可以加载图片了。很简单。
注意最后显示图片的步骤必须在main线程里。
其中涉及到task,简单来说就是任务。比如上传数据,下载数据等任务。NSURLSessionTask是父类,一般我们使用它的子类。NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。根据字面意思就了解。
如果是post请求,区别就是用request初始化task,提前设置request的HTTPMethod和HTTPBody等。
二、实现代理方法
简单的使用根据block直接得到数据,如果想在接受数据的过程中做进一步的数据处理,比如监听数据进度 、显示或者隐藏加载指示器等。可以在代理方法中做处理。
由于在代理方法中接受数据,block的形式不用了。初始化也有点不一样了
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:[NSURLRequest requestWithURL:url]];
记得遵守代理
@interface ThirdVC () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
@property (strong, nonatomic) NSURLSession *session;
@property (nonatomic, strong) UIImageView *imgv;
@property (nonatomic, assign) NSInteger dataSize;
@property (nonatomic, strong) NSMutableData *data;
@end
代理方法
#pragma mark session delegate
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
// 请求数据的大小。根据response获得。
// 初始化data
self.dataSize = response.expectedContentLength;
self.data = [[NSMutableData alloc] initWithCapacity:self.dataSize];
// 响应服务器,是否允许响应。
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 接收数据,可能调用多次。可以用来监听下载状态。
NSLog(@"666_SunDePrint_999:%ld", data.length);
// 多次拼接传回来的data
[self.data appendData:data];
if (self.data.length == self.dataSize) {
dispatch_async(dispatch_get_main_queue(), ^{
self.imgv.image = [UIImage imageWithData:self.data];
});
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// 请求成功或者失败
if (error == nil) {
NSLog(@"666_SunDePrint_999请求:%@", @"成功");
}else{
NSLog(@"666_SunDePrint_999请求:%@", @"失败");
}
}
根据NSURLSessionConfiguration初始化session。暂时使用默认的配置。根据response的信息,知道数据总的大小,在多次接收data后,判断data的length,如果等于数据大小,就表明数据传递完毕。可以显示图片了。
NSURLSessionUploadTask
在NSURLSession中,文件上传方式主要有以下两种:
直接传文件和上传二进制data。和AFN类似。
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) {
}];
断点下载(没做实际操作,不太了解)
NSURLSessionDownloadTask提供了与断点下载相关的几个方法:
// 使用这种方式取消下载可以得到将来用来恢复的数据,保存起来
[task cancelByProducingResumeData:^(NSData *resumeData) {
self.data = resumeData;
}];
// 由于下载失败导致的下载中断会进入此协议方法,也可以得到用来恢复的数据
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 保存恢复数据
self.data = error.userInfo[NSURLSessionDownloadTaskResumeData];
}
// 恢复下载时接过保存的恢复数据
task = [self.session downloadTaskWithResumeData:self.data];
// 启动任务
[task resume];