NSURLSession\NSURLSessionDownloadTask實現下載任務

之前講了使用NSURLSession實現一般的http報文收發,用到了簡易的block返回數據代理了代理消息的高顆粒交互。但是如果現在要用session來實現下載任務,就最好使用delegate消息來進行下載交互了。因為通過代理我們可以監控整個下載的過程,拿到下載的進度。我還是用上次的那個demo,下載地址是:https://github.com/yan0219/iosNetTest 效果如下圖所示,點一下下載數據,就啟動一個下載任務。任務會顯示進度,下載完成后會顯示完成。


下面就具體說一下實現一個下載任務的步驟吧。

1.第一步初始化session,與上節課相同,先使用default的配置初始化session,下次講到后臺下載的時候會用到另外一種background的配置初始化session。

//初始化一個NSUrlSession對象,之后的報文發送都使用該對象

- (void)initSession

{

? ? //初始化一個session的配置對象

? ? NSURLSessionConfiguration* yConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];


? ? /*初始化一個session對象,其中三個參數分別是

?? ? *configuration:配置對象

?? ? *delegate:session處理代理的對象

?? ? *delegateQueue:代理的消息處理的線程,這里傳mainQueue,代理的消息都會在主線程中收到

? ? */

? ? self.curSession = [NSURLSession sessionWithConfiguration:yConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

}

2.第二步,初始化下載任務,并啟動下載

這里直接用一個node軟件包的下載地址做測試,大小是15M左右。

- (void)downLoadTask

{

? ? NSURL* downloadURL = [NSURL URLWithString:@"https://nodejs.org/dist/v8.11.4/node-v8.11.4.pkg"];

? ? NSURLSessionDownloadTask* task = [self.curSessiondownloadTaskWithURL:downloadURL];


? ? NSMutableDictionary* taskDic = [NSMutableDictionary dictionaryWithObjectsAndKeys:task,@"task",[NSNumber numberWithFloat:0.0],@"progress", nil];

? ? [self.downloadTaskArray addObject:taskDic];


? ? [self.dTableView reloadData];


? ? [taskresume];

}

3.第三步實現NSURLSessionDownloadTaskDelegate的代理方法。監控下載進度和下載結果,并且在下載完成的時候將臨時文件移動到沙盒中存儲。


- (void)URLSession:(NSURLSession*)session downloadTask:(NSURLSessionDownloadTask*)downloadTask

didFinishDownloadingToURL:(NSURL*)location

{

? ? //下載任務完成時會調用該代理方法,可以在該方法中將下載的臨時文件移動到沙盒中保存,當該代理方法返回時,臨時文件將被刪除

? ? NSLog(@"NSURLSessionDownloadDelegate-------------didFinishDownloadingToURL");


? ? for(inti =0; i<[self.downloadTaskArraycount]; i++)

? ? {

? ? ? ? NSMutableDictionary* taskDic = [self.downloadTaskArrayobjectAtIndex:i];

? ? ? ? NSURLSessionDownloadTask* task = [taskDicobjectForKey:@"task"];

? ? ? ? if([taskisEqual:downloadTask])

? ? ? ? {

? ? ? ? ? ? [taskDicsetObject:[NSNumber numberWithFloat:2.0] forKey:@"progress"];

? ? ? ? ? ? [self.dTableViewreloadData];

? ? ? ? ? ? break;

? ? ? ? }

? ? }



? ? NSError*error;

? ? NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

? ? NSString*savePath = [cachePathstringByAppendingPathComponent:@"YDownload/node-v8.11.4.pkg"];

? ? NSURL*saveUrl = [NSURLfileURLWithPath:savePath];

? ? // 通過文件管理 復制文件

? ? [[NSFileManager defaultManager] copyItemAtURL:location toURL:saveUrl error:&error];

? ? if(error) {

? ? ? ? NSLog(@"Error is %@", error.localizedDescription);

? ? }


}

/* Sent periodically to notify the delegate of download progress. */

- (void)URLSession:(NSURLSession*)session downloadTask:(NSURLSessionDownloadTask*)downloadTask

? ? ? didWriteData:(int64_t)bytesWritten

?totalBytesWritten:(int64_t)totalBytesWritten

totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

{

? ? //下載過程中,反饋下載進度

? ? NSLog(@"NSURLSessionDownloadDelegate-------------didWriteData");

? ? floatprogress = totalBytesWritten *1.0/totalBytesExpectedToWrite;


? ? for(inti =0; i<[self.downloadTaskArraycount]; i++)

? ? {

? ? ? ? NSMutableDictionary* taskDic = [self.downloadTaskArrayobjectAtIndex:i];

? ? ? ? NSURLSessionDownloadTask* task = [taskDicobjectForKey:@"task"];

? ? ? ? if([taskisEqual:downloadTask])

? ? ? ? {

? ? ? ? ? ? [taskDicsetObject:[NSNumbernumberWithFloat:progress]forKey:@"progress"];

? ? ? ? ? ? [self.dTableViewreloadData];

? ? ? ? ? ? break;

? ? ? ? }

? ? }


}


4.剩下的就是在tableView中顯示下載進度了。這個就不贅述了。大家可以看具體代碼實現。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容