iOS网络开发之NSURLSession学习<2>

这篇文章主要介绍了NSURLSession以及NSURLSessionTask这个抽象类,和NSURLSessionDataTask的使用和代理方法。

一.NSURLSessionTask的介绍

Task是由Session创建的,Session会保持对Task的一个强引用,直到Task完成或者出错才会释放。通过NSURLSessionTask可以获得Task的各种状态,以及对Task进行取消,挂起,继续等操作。一共包括三种Task,三种Task的结构如图。本文主要讲解的是DataTask。

1.管理task的状态的方法

  • -(void)cancel //取消一个task
  • -(void)resume//如果task在挂起状态,则继续执行task
  • (void)suspend//挂起task

2.获得task的执行情况的属性

  • countOfBytesExpectedToReceive
  • countOfBytesReceivedcountOfBytesExpectedToSendcountOfBytesSent

3.task的综合信息

  • currentRequest // 当前活跃的request
  • originalRequest // 在task创建的时候传入的request(有可能会重定向)
  • response // 服务器对当前活跃请求的响应
  • taskDescription // 描述当前task
  • taskIdentifier// 用来区分Task的描述符
  • error //Task失败的错误信息

4.task状态的枚举

typedef NS_ENUM (NSInteger, NSURLSessionTaskState ) { NSURLSessionTaskStateRunning = 0, NSURLSessionTaskStateSuspended = 1, NSURLSessionTaskStateCanceling = 2, NSURLSessionTaskStateCompleted = 3,};

二.NSURLSessionDataTask代理

DataTask是用来干嘛的呢? 用来下载数据到内存里,数据的格式是NSData

dataTask使用的过程中,有两种方式来处理结果

  1. 通过block的方式(不关注过程,只关注结果,使用简单)
    下载一幅图片,完成后显示到ImageView。代码:
NSURLSessionDataTask * task = [self.session dataTaskWithURL:[NSURL URLWithString:imageURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (!error) {            
    UIImage * image = [UIImage imageWithData:data]; 
    self.imageview.image = image;                              
    }    
}]; 
[task resume];
  • 通过代理方法来管理session和task。( 可以获得全部过程,但是较为复杂)
    1.NSURLSessionDelegate用来处理Session层次的事件
    2.NSURLSessionTaskDelegate是使用代理的时候,任何种类task都要实现的代理
    3.NSURLSessionDataDelegate特别用来处理dataTask的事件

代码示例:

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDelegate,NSURLSessionTaskDelegate,NSURLSessionDataDelegate>

@property (strong,nonatomic)UIImageView * imageview;
@property (strong,nonatomic)NSURLSession * session;
@property (strong,nonatomic)NSURLSessionDataTask * dataTask;
@property (weak, nonatomic) IBOutlet UIProgressView *progressview;
@property (nonatomic)NSUInteger expectlength;
@property (strong,nonatomic) NSMutableData * buffer;
@end

static NSString * imageURL = @"http://f12.topit.me/o129/10129120625790e866.jpg";

@implementation ViewController//属性全部采用惰性初始化
#pragma mark - lazy property

-(UIImageView *)imageview{    
if (!_imageview) {        
_imageview = [[UIImageView alloc] initWithFrame:CGRectMake(40,40,300,200)];        _imageview.backgroundColor = [UIColor lightGrayColor];        _imageview.contentMode = UIViewContentModeScaleToFill;    }    
return _imageview;}

-(NSMutableData *)buffer{    
if (!_buffer) {        
_buffer = [[NSMutableData alloc] init];    
}    
return _buffer;}

-(NSURLSession*)session{    
if (!_session) {        
NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];        
_session = [NSURLSession sessionWithConfiguration:configuration                                                 delegate:self                                            delegateQueue:[NSOperationQueue mainQueue]];    }    return _session;}

-(NSURLSessionDataTask *)dataTask{    
if (!_dataTask) {        
_dataTask = [self.session dataTaskWithURL:[NSURL URLWithString:imageURL]];    }    
return _dataTask;}

#pragma mark - life circle of viewcontroller

- (void)viewDidLoad {    
[self.view addSubview:self.imageview];  

[self.dataTask resume];//Task要resume彩绘进行实际的数据传输    

[self.session finishTasksAndInvalidate];//完成task就invalidate
}


#pragma mark - target-action//注意判断当前Task的状态

- (IBAction)pause:(UIButton *)sender {    
 if (self.dataTask.state == NSURLSessionTaskStateRunning) {
    [self.dataTask pause]; 
}
}        

- (IBAction)cancel:(id)sender {  

if (self.dataTask.state == NSURLSessionTaskStateRunning||self.dataTask.state ==NSURLSessionTaskStateSuspended) { 
[self.dataTask cancel];            
 }
 }

- (IBAction)resume:(id)sender {    

if (self.dataTask.state == NSURLSessionTaskStateSuspended) {        [self.dataTask resume];    
}}


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

NSUInteger length = [response expectedContentLength];    

if (length != -1) {        
self.expectlength = [response expectedContentLength];//存储一共要传输的数据长度 

completionHandler(NSURLSessionResponseAllow);//继续数据传输    
}else{        completionHandler(NSURLSessionResponseCancel);//如果Response里不包括数据长度的信息,就取消数据传输        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"error"                                                         message:@"Do not contain property of expectedlength"                                                        delegate:nil                                               cancelButtonTitle:@"OK"                                               otherButtonTitles:nil];        

[alert show];    }}

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

[self.buffer appendData:data];//数据放到缓冲区里    

self.progressview.progress = [self.buffer length]/((float) self.expectlength);//更改progressview的progress}

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

if (!error) {        dispatch_async(dispatch_get_main_queue(), ^{//用GCD的方式,保证在主线程上更新UI            

UIImage * image = [UIImage imageWithData:self.buffer];            self.imageview.image = image;            self.progressview.hidden = YES;            self.session = nil;            
self.dataTask = nil;        
});    
}else{        
NSDictionary * userinfo = [error userInfo];        NSString * failurl = [userinfo objectForKey:NSURLErrorFailingURLStringErrorKey];        NSString * localDescription = [userinfo objectForKey:NSLocalizedDescriptionKey];        

if ([failurl isEqualToString:imageURL] && [localDescription isEqualToString:@"cancelled"]) {
//如果是task被取消了,就弹出提示框            

UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Message"                                                             message:@"The task is canceled"                                                            delegate:nil                                                   cancelButtonTitle:@"OK"                                                   otherButtonTitles:nil];            
[alert show];        
}else{            
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Unknown type error"//其他错误,则弹出错误描述                                                             message:error.localizedDescription                                                            delegate:nil                                                   cancelButtonTitle:@"OK"                                                   otherButtonTitles:nil];            
[alert show];        
}        

self.progressview.hidden = YES;        
self.session = nil;        
self.dataTask = nil;    
}}

@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值