標籤:
NSURLConnection通過全域狀態來管理cookies、認證資訊等公用資源,這樣如果遇到兩個串連需要使用不同的資源配置情況時就無法解決了,但是這個問題在NSURLSession中得到瞭解決。NSURLSession同時對應著多個串連,會話通過Factory 方法來建立,同一個會話中使用相同的狀態資訊。NSURLSession支援進程三種會話:
defaultSessionConfiguration:進程內會話(預設會話),用硬碟來快取資料。
ephemeralSessionConfiguration:臨時的進程內會話(記憶體),不會將cookie、緩衝儲存到本地,只會放到記憶體中,當應用程式退出後資料也會消失。
backgroundSessionConfiguration:後台會話,相比預設會話,該會話會在後台開啟一個線程進行網路資料處理。
下面將通過一個檔案下載功能對兩種會話進行示範,在這個過程中也會用到任務的代理方法對上傳操作進行更加細緻的控制。下面先看一下使用預設會話下載檔案,代碼中示範了如何通過NSURLSessionConfiguration進行會話配置,如果通過代理方法進行檔案下載進度展示(類似於前面中使用NSURLConnection代理方法,其實下載並未分段,如果需要分段需要配合後台進行),同時在這個過程中可以準確控制任務的取消、掛起和恢複。
//// ViewController.m// NSURLSession會話//// Copyright © 2016年 asamu. All rights reserved.//#import "ViewController.h"@interface ViewController ()<NSURLSessionDownloadDelegate>{ NSURLSessionDownloadTask *_downloadTask;}@property (weak, nonatomic) IBOutlet UITextField *textField;@property (weak, nonatomic) IBOutlet UIProgressView *progressView;@property (weak, nonatomic) IBOutlet UILabel *label;@property (weak, nonatomic) IBOutlet UIButton *downBtn;@end@implementation ViewController#pragma mark -- UI方法- (void)viewDidLoad { [super viewDidLoad]; _progressView.progress = 0;}#pragma mark 按鈕點擊事件- (IBAction)download:(id)sender { NSString *filename = _textField.text; NSString *urlStr = [NSString stringWithFormat:@"http://mr7.doubanio.com/832d52e9c3df5c13afd7243a770c094f/0/fm/song/p294_128k.mp3",filename]; NSURL *url = [NSURL URLWithString:urlStr]; //建立請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //建立會話 //預設會話 NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; //請求超過時間 sessionConfiguration.timeoutIntervalForRequest = 5.0f; //是否允許使用蜂窩 sessionConfiguration.allowsCellularAccess = true; //建立會話 NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil]; _downloadTask = [session downloadTaskWithRequest:request]; [_downloadTask resume];}- (IBAction)cancel:(id)sender { [_downloadTask cancel]; _label.text = @"Cancel";}- (IBAction)suspend:(id)sender { [_downloadTask suspend]; _label.text =@"Suspend";}- (IBAction)resume:(id)sender { [_downloadTask resume];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning];}#pragma mark - 設定介面狀態-(void)setUIStatus:(int64_t)totalBytesWritten expectedTowrite:(int64_t)totalBytesExpectedWritten{ //更新 UI 放到主線程 dispatch_async(dispatch_get_main_queue(), ^{ //設定進度條 _progressView.progress = (float)totalBytesWritten / totalBytesExpectedWritten; if (totalBytesWritten == totalBytesExpectedWritten) { _label.text = @"Finish download"; //關網 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; _downBtn.enabled = YES; }else{ _label.text = @"Downing..."; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } });}#pragma mark - 下載任務代理#pragma mark 下載中(會多次調用,可以記錄下載進度)-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ [self setUIStatus:totalBytesWritten expectedTowrite:totalBytesExpectedToWrite];}#pragma mark 下載完成-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSError *error; //注釋見上篇,懶得寫。。。 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]; NSString *savePath = [cachePath stringByAppendingPathComponent:_textField.text]; NSLog(@"%@",savePath); NSURL *url = [NSURL fileURLWithPath:savePath]; [[NSFileManager defaultManager]moveItemAtURL:location toURL:url error:&error]; if (error) { NSLog(@"%@",error.localizedDescription); }}#pragma mark 任務完成,不管是否下載成功-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ if (error) { NSLog(@"%@",error.localizedDescription); }}@end
Storyboard如右圖:
iOS學習-10下載(4) NSURLSession 會話 篇