NSURLSession學習筆記(一)簡介

1、URL Session的基本概念html

1.三種工做模式:ios

默認會話模式(default):工做模式相似於原來的NSURLConnection,使用的是基於磁盤緩存的持久化策略,使用用戶keychain中保存的證書進行認證受權。緩存

瞬時會話模式(ephemeral):該模式不使用磁盤保存任何數據。全部和會話相關的caches,證書,cookies等都被保存在RAM中,所以當程序使會話無效,這些緩存的數據就會被自動清空。性能優化

後臺會話模式(background):該模式在後臺完成上傳和下載,在建立Configuration對象的時候須要提供一個NSString類型的ID用於標識完成工做的後臺會話。cookie


2.NSURLSession支持的三種任務網絡

NSURLSession類支持三種類型的任務:加載數據,下載和上傳。session


2、相關的類app

NSURLConnection這個名字,實際上指的是一組構成Foundation框架中URL加載系統的相互關聯的組件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
框架

在WWDC 2013中,Apple的團隊對NSURLConnection進行了重構,並推出了NSURLSession做爲替代。async

NSURLSession也是一組相互依賴的類,它的大部分組件和NSURLConnection中的組件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一樣之處在於,它將NSURLConnection替換爲NSURLSession和NSURLSessionConfiguration,以及3個NSURLSessionTask的子類:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。


下面來講下NSURLSession新推出的類:

1.NSURLSessionConfiguration類

其中NSURLSessionConfiguration用於配置會話的屬性,能夠經過該類配置會話的工做模式:


+ (NSURLSessionConfiguration *)defaultSessionConfiguration;  
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;  
+ (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier;


在backgroundSessionConfiguration:方法中的identifier參數指定了會話的ID,用於標記後臺的session。

該類的其中兩個屬性:

/* allow request to route over cellular. */  
@property BOOL allowsCellularAccess;  
  
/* allows background tasks to be scheduled at the discretion of the system for optimal performance. */  
@property (getter=isDiscretionary) BOOL discretionary NS_AVAILABLE(NA, 7_0);


allowsCellularAccess 屬性指定是否容許使用蜂窩鏈接, discretionary屬性爲YES時表示當程序在後臺運做時由系統本身選擇最佳的網絡鏈接配置,該屬性能夠節省經過蜂窩鏈接的帶寬。在使用後臺傳輸數據的時候,建議使用discretionary屬性,而不是allowsCellularAccess屬性,由於它會把WiFi和電源可用性考慮在內。補充:這個標誌容許系統爲分配任務進行性能優化。這意味着只有當設備有足夠電量時,設備才經過Wifi進行數據傳輸。若是電量低,或者只僅有一個蜂窩鏈接,傳輸任務是不會運行的。後臺傳輸老是在discretionary模式下運行。


2.NSURLSession類

獲取NSURLSession類對象有幾種方式:

/*
 * The shared session uses the currently set global NSURLCache,
 * NSHTTPCookieStorage and NSURLCredentialStorage objects.
 */
+ (NSURLSession *)sharedSession;
/*
 * Customization of NSURLSession occurs during creation of a new session.
 * If you only need to use the convenience routines with custom
 * configuration options it is not necessary to specify a delegate.
 * If you do specify a delegate, the delegate will be retained until after
 * the delegate has been sent the URLSession:didBecomeInvalidWithError: message.
 */
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;


第一種方式是使用靜態的sharedSession方法,該類使用共享的會話,該會話使用全局的Cache,Cookie和證書。

第二種方式是經過sessionWithConfiguration:方法建立對象,也就是建立對應配置的會話,與NSURLSessionConfiguration合做使用。

第三種方式是經過sessionWithConfiguration:delegate:delegateQueue方法建立對象,二三兩種方式能夠建立一個新會話並定製其會話類型。該方式中指定了session的委託和委託所處的隊列。當再也不須要鏈接時,能夠調用Session的invalidateAndCancel直接關閉,或者調用finishTasksAndInvalidate等待當前Task結束後關閉。這時Delegate會收到URLSession:didBecomeInvalidWithError:這個事件。Delegate收到這個事件以後會被解引用。


3.NSURLSessionTask類

NSURLSessionTask是一個抽象子類,它有三個子類:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。這三個類封裝了現代應用程序的三個基本網絡任務:獲取數據,好比JSON或XML,以及上傳和下載文件。

下面是其繼承關係:


有多種方法建立對應的任務對象:

(1)NSURLSessionDataTask

經過request對象或url建立:

/* Creates a data task with the given request.  The request may have a body stream. */  
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;  
  
/* Creates a data task to retrieve the contents of the given URL. */  
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;


經過request對象或url建立,同時指定任務完成後經過completionHandler指定回調的代碼塊:

 /* 
 * data task convenience methods.  These methods create tasks that 
 * bypass the normal delegate calls for response and data delivery, 
 * and provide a simple cancelable asynchronous interface to receiving 
 * data.  Errors will be returned in the NSURLErrorDomain,  
 * see <Foundation/NSURLError.h>.  The delegate, if any, will still be 
 * called for authentication challenges. 
 */  
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;


(2)NSURLSessionUploadTask

經過request建立,在上傳時指定文件源或數據源。

/* Creates an upload task with the given request.  The body of the request will be created from the file referenced by fileURL */  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;  
  
/* Creates an upload task with the given request.  The body of the request is provided from the bodyData. */  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;  
  
/* Creates an upload task with the given request.  The previously set body stream of the request (if any) is ignored and the URLSession:task:needNewBodyStream: delegate will be called when the body payload is required. */  
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;


在建立upload task對象時,經過completionHandler指定任務完成後的回調代碼塊:

/* 
 * upload convenience method. 
 */  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;


(3)NSURLSessionDownloadTask

/* Creates a download task with the given request. */  
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;  
  
/* Creates a download task to download the contents of the given URL. */  
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;  
  
/* Creates a download task with the resume data.  If the download cannot be successfully resumed, URLSession:task:didCompleteWithError: will be called. */  
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;


下載任務支持斷點續傳,第三種方式是經過以前已經下載的數據來建立下載任務。
一樣地能夠經過completionHandler指定任務完成後的回調代碼塊:

/* 
 * download task convenience methods.  When a download successfully 
 * completes, the NSURL will point to a file that must be read or 
 * copied during the invocation of the completion routine.  The file 
 * will be removed automatically. 
 */  
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;


4.NSURLSessionDelegate和NSURLSessionTaskDelegate協議

在協議的方法中能夠完成各類各樣的回調動做,如身份驗證、完成任務後的動做、錯誤處理和後臺任務完成的動做等。委託方法指定在NSURLSession中必定數量的字節傳輸使用int64_t類型的參數。

這裏只說下後臺任務的一個委託方法:

/* If an application has received an 
 * -application:handleEventsForBackgroundURLSession:completionHandler: 
 * message, the session delegate will receive this message to indicate 
 * that all messages previously enqueued for this session have been 
 * delivered.  At this time it is safe to invoke the previously stored 
 * completion handler, or to begin any internal updates that will 
 * result in invoking the completion handler. 
 */  
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session NS_AVAILABLE_IOS(7_0);


合做使用的ApplicationDelegate方法:

// Applications using an NSURLSession with a background configuration may be launched or resumed in the background in order to handle the  
// completion of tasks in that session, or to handle authentication. This method will be called with the identifier of the session needing  
// attention. Once a session has been created from a configuration object with that identifier, the session's delegate will begin receiving  
// callbacks. If such a session has already been created (if the app is being resumed, for instance), then the delegate will start receiving  
// callbacks without any action by the application. You should call the completionHandler as soon as you're finished handling the callbacks.  
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler NS_AVAILABLE_IOS(7_0);


將任務切換到後臺以後,Session的Delegate不會再收到和Task相關的消息。當全部Task全都完成後,程序將被喚醒,並調用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回調,在這裏要爲後臺session(由background session的identifier標識)指定對應的回調代碼塊。

隨後,對於每個完成的後臺Task調用該Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的話)和URLSession:task:didCompleteWithError:(成功或者失敗都會調用)方法作處理,以上的回調代碼塊能夠在這裏調用。



本文參考的資料包括:

iOS 7系列譯文:忘記NSURLConnection,擁抱NSURLSession吧!

NSURLSession使用說明及後臺工做流程分析

Using NSURLSession

objc.io #5 iOS 7 From NSURLConnection to NSURLSession

相關文章
相關標籤/搜索