IOS 網路開發NSURLSession(三)DownloadTask,nsurlsession
原創Blog,轉載請註明出處
blog.csdn.net/hello_hwc
Demo 效果
下載一個URL,然後顯示的ImageView並且儲存到相簿
之前的相簿
儲存圖片後的相簿
一 DownloadTask和DataTask的區別
簡而言之,DownloadTask是把檔案直接download到磁碟。
詳細來說,有以下幾點區別
二 用Block的方式來處理DownloadTask
這種情況下和DataTask類似,處理起來比較簡單,但是不靈活。
其中,Location是download臨時檔案儲存體的路徑
self.downloadTask = [self.session downloadTaskWithURL:(NSURL *) completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { }];
繼續上一次儲存的資料下載
self.downloadTask = [self.session downloadTaskWithResumeData:(NSData *) completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { }]
這裡的ResumeData是通過
[self.downloadTask cancelByProducingResumeData:^(NSData *resumeData)completionHandler]
或者在Session的代理函數的Error中儲存,Key是NSURLSessionDownloadTaskResumeData
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
三 用代理的方式處理
除了NSURLSessionDelegate用來處理Session層次的事件,NSURLSessionTaskDelegate處理Task的共性事件之外,還有NSURLSessionDownloadTaskDelegate 用來特別處理Download事件。
幾個主要函數
每次在用上文中的ResumeData建立DownloadTask之後,然後讓task開始執行,這個函數就會調用。
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffsetexpectedTotalBytes:(int64_t)expectedTotalBytes
下載的進度
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWrittentotalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
下載完成的事件
注意,一定要在這個函數返回之前,對資料進行使用,或者儲存
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidFinishDownloadingToURL:(NSURL *)location
四 Demo講解
Demo比較簡單,
@interface DownloadTaskViewController()<NSURLSessionDelegate,NSURLSessionTaskDelegate,NSURLSessionDownloadDelegate,UITextFieldDelegate>@property (strong,nonatomic)NSURLSession * session;@property (strong,nonatomic)NSURLSessionDownloadTask * downloadTask;@property (weak, nonatomic) IBOutlet UITextField *urltextfield;@property (weak, nonatomic) IBOutlet UIImageView *imageview;@property (weak, nonatomic) IBOutlet UIProgressView *progressview;@end@implementation DownloadTaskViewController//開始下載- (IBAction)download:(id)sender { self.progressview.hidden = NO; self.progressview.progress = 0.0; NSString * imageurl = self.urltextfield.text; self.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:imageurl]]; [self.downloadTask resume]; [self.session finishTasksAndInvalidate];}//初始化-(void)viewDidLoad{ self.urltextfield.delegate = self; NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"id"]; self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];}//Session層次的Task完成的事件-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ if (error) { UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } self.progressview.hidden = YES;}//Task完成的事件-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSData * data = [NSData dataWithContentsOfURL:location.filePathURL]; UIImage * image = [UIImage imageWithData:data]; self.imageview.image = image; UIImageWriteToSavedPhotosAlbum(image, nil,nil,nil); self.session = nil;}-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{}//下載進度的代理-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ if (totalBytesExpectedToWrite != NSURLSessionTransferSizeUnknown) { self.progressview.progress = totalBytesWritten/(float)totalBytesExpectedToWrite; }}//TextField Delegate-(BOOL)textFieldShouldReturn:(UITextField *)textField{ [self.urltextfield resignFirstResponder]; return YES;}@end