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吧!
objc.io #5 iOS 7 From NSURLConnection to NSURLSession