與 NSURLConnection 相比,NSURLsession 最直接的改進就是能夠配置每一個 session 的緩存,協議,cookie,以及證書策略(credential policy),甚至跨程序共享這些信息。這將容許程序和網絡基礎框架之間相互獨立,不會發生干擾。每一個 NSURLSession 對象都由一個 NSURLSessionConfiguration 對象來進行初始化,後者指定了剛纔提到的那些策略以及一些用來加強移動設備上性能的新選項。
NSURLSession 中另外一大塊就是 session task。它負責處理數據的加載以及文件和數據在客戶端與服務端之間的上傳和下載。NSURLSessionTask 與 NSURLConnection 最大的類似之處在於它也負責數據的加載,最大的不一樣之處在於全部的 task 共享其創造者 NSURLSession 這一公共委託者(common delegate)。
NSURLSession
NSURLSession 是 iOS 7 新引入的用於替代 NSURLConnection 的類。
NSURLSession提供的功能:
1.經過URL將數據下載到內存
2.經過URL將數據下載到文件系統
3.將數據上傳到指定URL
4.在後臺完成上述功能
1.建立一個NSURLSessionConfiguration,用於第二步建立NSSession時設置工做模式和網絡設置:
工做模式分爲:
通常模式(default):工做模式相似於原來的NSURLConnection,可使用緩存的Cache,Cookie,鑑權。
及時模式(ephemeral):不使用緩存的Cache,Cookie,鑑權。
後臺模式(background):在後臺完成上傳下載,建立Configuration對象的時候須要給一個NSString的ID用於追蹤完成工做的Session是哪個(後面會講到)。
網絡設置:參考NSURLConnection中的設置項。
1. 建立一個NSURLSession,系統提供了兩個建立方法:
sessionWithConfiguration:
sessionWithConfiguration:delegate:delegateQueue:
第一個粒度較低就是根據剛纔建立的Configuration建立一個Session,系統默認建立一個新的OperationQueue處理Session的消息。
第二個粒度比較高,能夠設定回調的delegate(注意這個回調delegate會被強引用),而且能夠設定delegate在哪一個OperationQueue回調,若是咱們將其設置爲[NSOperationQueue mainQueue]就能在主線程進行回調很是的方便。
2.建立一個NSURLRequest調用剛纔的NSURLSession對象提供的Task函數,建立一個NSURLSessionTask。
NSURLSessionConfiguration * config=[NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session=[NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
NSURL *url=[NSURL URLWithString:@src];
NSURLRequest * request=[NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *task= [_session downloadTaskWithRequest:_request];
[_task resume];
根據職能不一樣Task有三種子類:
NSURLSessionUploadTask:上傳用的Task,傳完之後不會再下載返回結果;
NSURLSessionDownloadTask:下載用的Task;
NSURLSessionDataTask:能夠上傳內容,上傳完成後再進行下載。
3.若是是細粒度的Session調用,Session與Delegate會在指定的OperationQueue中進行交互,以我們下載例子,交互過程的順序圖以下(假如不須要鑑權,即非HTTPS請求):
4.當再也不須要鏈接調用Session的invalidateAndCancel直接關閉,或者調用finishTasksAndInvalidate等待當前Task結束後關閉。這時Delegate會收到URLSession:didBecomeInvalidWithError:這個事件。Delegate收到這個事件以後會被解引用。
NSURLSession相關的類
NSURLConnection這個名字,實際上指的是一組構成Foundation框架中URL加載系統的相互關聯的組件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
在WWDC2013中,Apple的團隊對NSURLConnection進行了重構,並推出了NSURLSession做爲替代。
NSURLSession也是一組相互依賴的類,它的大部分組件和NSURLConnection中的組件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一樣之處在於,它將NSURLConnection替換爲NSURLSession和NSURLSessionConfiguration,以及3個NSURLSessionTask的子類:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。
NSURLSessionConfiguration
NSURLSessionConfiguration用於配置會話的屬性,能夠經過該類配置會話的工做模式:
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
方法中的identifier參數指定了會話的ID,用於標記後臺的session。
@property BOOL allowsCellularAccess;//是否容許使用蜂窩鏈接
@property (getter=isDiscretionary) BOOL discretionary NS_AVAILABLE(10_10, 7_0);
discretionary=yes 表示當程序在後臺運做時由系統本身選擇最佳的網絡鏈接配置,該屬性能夠節省經過蜂窩鏈接的帶寬。建議使用discretionary屬性,而不是allowsCellularAccess屬性,由於它會把WiFi和電源可用性考慮在內。
NSURLSession
+ (NSURLSession *)sharedSession;
使用靜態的sharedSession方法,該類使用共享的會話,該會話使用全局的Cache,Cookie和證書。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
方法建立對象,也就是建立對應配置的會話,與NSURLSessionConfiguration合做使用。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
經過sessionWithConfiguration:delegate:delegateQueue方法建立對象,二三兩種方式能夠建立一個新會話並定製其會話類型。該方式中指定了session的委託和委託所處的隊列。當再也不須要鏈接時,能夠調用Session的invalidateAndCancel直接關閉,或者調用finishTasksAndInvalidate等待當前Task結束後關閉。這時Delegate會收到URLSession:didBecomeInvalidWithError:這個事件。Delegate收到這個事件以後會被解引用。
NSURLSessionTask
NSURLSessionTask是一個抽象子類,它有三個子類:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。這三個類封裝了現代應用程序的三個基本網絡任務:獲取數據,好比JSON或XML,以及上傳和下載文件。斷點續傳
當一個 NSURLSessionDataTask 完成時,它會帶有相關聯的數據,而一個 NSURLSessionDownloadTask 任務結束時,它會帶回已下載文件的一個臨時的文件路徑。由於通常來講,服務端對於一個上傳任務的響應也會有相關數據返回,因此 NSURLSessionUploadTask 繼承自 NSURLSessionDataTask。
不一樣於直接使用 alloc-init 初始化方法,task 是由一個 NSURLSession 建立的。每一個 task 的構造方法都對應有或者沒有 completionHandler 這個 block 的兩個版本,例如:有這樣兩個構造方法 –dataTaskWithRequest: 和 –dataTaskWithRequest:completionHandler:。這與 NSURLConnection 的 -sendAsynchronousRequest:queue:completionHandler: 方法相似,經過指定 completionHandler 這個 block 將建立一個隱式的 delegate,來替代該 task 原來的 delegate——session。對於須要 override 原有 session task 的 delegate 的默認行爲的狀況,咱們須要使用這種不帶 completionHandler 的版本。
NSURLConnection:
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // ... }];
NSURLSession:
在 task 的構造方法上延續了這一模式。不一樣的是,這裏不會當即運行 task,而是將該 task 對象先返回,容許咱們進一步的配置,而後可使用 resume 方法來讓它開始運行。
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { // ... }];
[task resume];
Download task 也須要一個 request,不一樣之處在於 completionHandler 這個 block。Data task 和 upload task 會在任務完成時一次性返回,可是 Download task 是將數據一點點地寫入本地的臨時文件。因此在 completionHandler 這個 block 裏,咱們須要把文件從一個臨時地址移動到一個永久的地址保存起來:
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler: ^(NSURL *location, NSURLResponse *response, NSError *error) {
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
NSURL *newFileLocation = [documentsDirectoryURL URLByAppendingPathComponent:[[response URL] lastPathComponent]];
[[NSFileManager defaultManager] copyItemAtURL:location toURL:newFileLocation error:nil]; }];
[downloadTask resume];
downloadTaskWithResumeData 斷點續傳
+ (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier 後臺下載
sessionWithConfiguration
NSURLSessionDownloadDelegate
爲了實現下載進度的顯示,須要在委託中的如下方法中實現:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
double downloadProgress = totalBytesWritten / (double)totalBytesExpectedToWrite;
-------------------------------------
AFJSONRequestOperation 是 AFHTTPRequestOperation 的子類,針對 JSON 類型請求作了特殊處理,在有了 AFHTTPRequestOperation+AFURLConnectionOperation 的基礎工做後,AFJSONRequestOperation 已經很是方便直接使用了。指定 acceptableContentTypes: 以支持 JSON,responseJSON 直接返回已經解析好的 JSON 數據對象。下載到 JSON 數據後在一單獨線程
AFXMLRequestOperation/AFPropertyListRequestOperation/AFImageRequestOperation 和 AFJSONRequestOperation 相似,針對 XML、Plist、image 類型請求作了一些處理。其中 AFImageRequestOperation 額外有一個 imageProcessingBlock,取到圖片後能夠在一個單獨線程 queque 對圖片進行處理,好比縮放、切圓角、圖片特效等,而後再交給 main_queue success block.
AFN 還提供了一個 UIImageView+AFNetworking category,能夠用 setImageWithURL: 來設置圖片。這個 cagetory 和 SDWebImage 相似但更簡單一些,圖片下載由 AFN 完成,圖片緩存由 NSCache 處理。