转:http://blog.csdn.net/hello_hwc/article/details/44565115
前言:
这是IOS 网络开发系列的第三篇文章,这篇文章主要介绍了NSURLSession以及NSURLSessionTask这个抽象类,和NSURLSessionDataTask的使用和代理方法。
本篇的顺序,
1. demo效果
2. NSURLSessionTask属性方法介绍
3. NSURLSessionDataTask的使用和代理方法
4. Demo的源码讲解
一 Demo效果
暂停-继续
取消
三 NSURLSessionTask
Task是由Session创建的,Session会保持对Task的一个强引用,直到Task完成或者出错才会释放。通过NSURLSessionTask可以获得Task的各种状态,以及对Task进行取消,挂起,继续等操作。一共包括三种Task,三种Task的结构如图。本文主要讲解的是DataTask。
管理task的状态的方法
- (void)cancel - (void)resume - (void)suspend
获得task的执行情况的属性
countOfBytesExpectedToReceive countOfBytesReceivedcountOfBytesExpectedToSendcountOfBytesSent
task的综合信息
currentRequest originalRequest response taskDescription taskIdentifier error
task状态的枚举
typedef NS_ENUM (NSInteger, NSURLSessionTaskState ) { NSURLSessionTaskStateRunning = 0, NSURLSessionTaskStateSuspended = 1, NSURLSessionTaskStateCanceling = 2, NSURLSessionTaskStateCompleted = 3,};
四 NSURLSessionDataTask代理
DataTask是用来干嘛的呢?
用来下载数据到内存里,数据的格式是NSData
dataTask使用的过程中,有两种方式来处理结果
第一种,通过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。( 可以获得全部过程,但是较为复杂)
主要使用到三种代理中的事件
NSURLSessionDelegate用来处理Session层次的事件
Session被 invalide得到的事件- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
Session层次收到了授权,证书等问题
- (void)URLSession:(NSURLSession *)sessiondidReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
NSURLSessionTaskDelegate是使用代理的时候,任何种类task都要实现的代理
Task完成的事件
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError *)error
Task层次收到了授权,证书等问题
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
将会进行HTTP,重定向
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskwillPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler
NSURLSessionDataDelegate特别用来处理dataTask的事件
收到了Response,这个Response包括了HTTP的header(数据长度,类型等信息),这里可以决定DataTask以何种方式继续(继续,取消,转变为Download)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTaskdidReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
DataTask已经转变成DownloadTask
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTaskdidBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
每收到一次Data时候调用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
是否把Response存储到Cache中
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler
五 Demo源码讲解
#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;@endstatic 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 { [super viewDidLoad]; [self.view addSubview:self.imageview]; [self.dataTask resume]; [self.session finishTasksAndInvalidate];}#pragma mark - target-action- (IBAction)pause:(UIButton *)sender { if (self.dataTask.state == NSURLSessionTaskStateRunning) { [self.dataTask suspend]; }}- (IBAction)cancel:(id)sender { switch (self.dataTask.state) { case NSURLSessionTaskStateRunning: case NSURLSessionTaskStateSuspended: [self.dataTask cancel]; break; default: break; }}- (IBAction)resume:(id)sender { if (self.dataTask.state == NSURLSessionTaskStateSuspended) { [self.dataTask resume]; }}#pragma mark - URLSession delegate method-(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); 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);}-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ if (!error) { dispatch_async(dispatch_get_main_queue(), ^{ 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"]) { 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
0 0