之前講了使用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中顯示下載進度了。這個就不贅述了。大家可以看具體代碼實現。