NSURLSession的使用

2017-11-03  本文已影响0人  请叫我魔法师

看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];

上一篇下一篇

猜你喜欢

热点阅读