iOSネットワーク開発NSURLSession(二)DataTask+Demo
21339 ワード
オリジナルblog、転載は出典blogを明記してください.csdn.net/hello_hwc
私のIOS-SDK解説コラムへようこそhttp://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
前言:これはIOSネットワーク開発シリーズの3番目の文章で、この文章は主にNSURLSessionとNSURLSessionTaskという抽象クラスとNSURLSessionDataTaskの使用と代理方法を紹介した.本編の手順、1.demo効果2.NSURLSessionTaskの属性方法紹介3.NSURLSessionDataTaskの使用とプロキシメソッド4.Demoのソース説明
一Demo効果
一時停止-継続キャンセル
三NSURLSessionTask
TaskはSessionによって作成され、SessionはTaskが完了するかエラーが発生するまでTaskへの強い参照を維持します.NSURLSessionTaskによりTaskの様々な状態が得られ,Taskのキャンセル,保留,継続などの操作が可能となる.全部で3種類のTaskを含んで、3種類のTaskの構造は図のようです.ここでは主にDataTaskについて説明します.
taskの状態を管理する方法
taskの実行状況のプロパティを取得する
taskの総合情報
task状態の列挙
4 NSURLSessionDataTaskエージェント
DataTaskは何に使いますか?メモリにデータをダウンロードするために使用されます.データのフォーマットはNSData dataTaskが使用する過程で、結果を処理する2つの方法があります.
1つ目は、block方式(プロセスに注目せず、結果だけに注目し、使用が簡単)
例を挙げて画像をダウンロードし、完了したらImageViewに表示します.次のコードは簡単に見えますね.
2つ目は,エージェントメソッドによりsessionとtaskを管理する.(すべてのプロセスが得られますが、複雑です)
主に3つのエージェントに使用されるイベントNSURLSessionDelegateは、Session階層のイベントを処理するために使用されます.
Session階層はライセンス、証明書などの問題を受け取った.
NSURLSessionTaskDelegateはエージェントを使用する場合、どの種類のtaskでも実現するエージェントTaskが完了するイベントです
Task階層はライセンス、証明書などの問題を受け取った.
HTTPを行い、リダイレクト
NSURLSessionDataDelegateは特にdataTaskのイベントを処理するためにResponseを受け取った.このResponseにはHTTPのヘッダ(データ長、タイプなどの情報)が含まれており、ここではDataTaskがどのように継続するか(継続、キャンセル、ダウンロードへの移行)を決定することができる.
DataTaskはDownloadTaskに変わりました
Dataを受信するたびに呼び出されます
ResponseをCacheに格納するかどうか
五Demoソース説明
私のIOS-SDK解説コラムへようこそhttp://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
前言:これはIOSネットワーク開発シリーズの3番目の文章で、この文章は主にNSURLSessionとNSURLSessionTaskという抽象クラスとNSURLSessionDataTaskの使用と代理方法を紹介した.本編の手順、1.demo効果2.NSURLSessionTaskの属性方法紹介3.NSURLSessionDataTaskの使用とプロキシメソッド4.Demoのソース説明
一Demo効果
一時停止-継続キャンセル
三NSURLSessionTask
TaskはSessionによって作成され、SessionはTaskが完了するかエラーが発生するまでTaskへの強い参照を維持します.NSURLSessionTaskによりTaskの様々な状態が得られ,Taskのキャンセル,保留,継続などの操作が可能となる.全部で3種類のTaskを含んで、3種類のTaskの構造は図のようです.ここでは主にDataTaskについて説明します.
taskの状態を管理する方法
- (void)cancel // task
- (void)resume // task , task
- (void)suspend // task
taskの実行状況のプロパティを取得する
countOfBytesExpectedToReceive
countOfBytesReceived
countOfBytesExpectedToSend
countOfBytesSent
taskの総合情報
currentRequest // request
originalRequest // task request( )
response //
taskDescription // task
taskIdentifier // Task
error //Task
task状態の列挙
typedef NS_ENUM (NSInteger,
NSURLSessionTaskState ) {
NSURLSessionTaskStateRunning = 0,
NSURLSessionTaskStateSuspended = 1,
NSURLSessionTaskStateCanceling = 2,
NSURLSessionTaskStateCompleted = 3,
};
4 NSURLSessionDataTaskエージェント
DataTaskは何に使いますか?メモリにデータをダウンロードするために使用されます.データのフォーマットはNSData dataTaskが使用する過程で、結果を処理する2つの方法があります.
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];
2つ目は,エージェントメソッドによりsessionとtaskを管理する.(すべてのプロセスが得られますが、複雑です)
主に3つのエージェントに使用されるイベントNSURLSessionDelegateは、Session階層のイベントを処理するために使用されます.
Session invalide
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
Session階層はライセンス、証明書などの問題を受け取った.
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
NSURLSessionTaskDelegateはエージェントを使用する場合、どの種類のtaskでも実現するエージェントTaskが完了するイベントです
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
Task階層はライセンス、証明書などの問題を受け取った.
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
HTTPを行い、リダイレクト
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
newRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLRequest *))completionHandler
NSURLSessionDataDelegateは特にdataTaskのイベントを処理するためにResponseを受け取った.このResponseにはHTTPのヘッダ(データ長、タイプなどの情報)が含まれており、ここではDataTaskがどのように継続するか(継続、キャンセル、ダウンロードへの移行)を決定することができる.
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
DataTaskはDownloadTaskに変わりました
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(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;
@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 {
[super 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 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);// 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