URL的組成:html
通常狀況是: 協議(scheme
)://主機名(host
):端口(port
)/服務器上資源的路徑(path
)?參數ios
例子:http://100.0.0.0:8080/xxx?id=3macos
通用格式:協議://用戶名(user
):密碼(password
)@主機名:端口/服務器上資源的路徑?參數#片斷(fragment
)瀏覽器
例子:ftp://joe:joepasswd@ftp.prep.edu/pub/name/xxx?id=3#name緩存
協議(scheme):
http
https
ftp
等等
用戶名和密碼:不少服務器都要求輸入用戶名和密碼纔會容許用戶訪問數據,如FTP服務器。
主機名(host):://
後邊的域名或者 ip。例如:htouhui.com
or100.0.0.0
端口(port)::
後邊的8080 路徑(path):端口後邊的第一個/
開始到?
結束,路徑說明了資源位於服務器的什麼地方 參數:?
後邊#
前邊 例如id=3
片斷(fragment):#
後邊的,例如name
安全
NSUrlRequest 是封裝了2個必要內容:URL和擴展服務器
URL:請求頭,請求體,輸入流,請求方法,超時時間等等
擴展:協議(Http https ftp 等等的成熟協議和自定義協議),緩存等等cookie
[注]:NSURLRequest
繼承NSSecureCoding
協議,NSSecureCoding
的前身是NSCoding
,NSSecureCoding
更加安全,主要目的是:繼承這個寫協議的類能夠和NSData互相轉換。網絡
緩存session
//緩存策略:
NSURLRequestUseProtocolCachePolicy = 0, //默認的緩存策略(取決於協議)
NSURLRequestReloadIgnoringLocalCacheData = 1, // 忽略緩存,從新請求
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2, // 有緩存就用緩存,沒有緩存就從新請求
NSURLRequestReturnCacheDataDontLoad = 3, // 有緩存就用緩存,沒有緩存就不發請求,當作請求出錯處理(用於離線模式)
NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
複製代碼
管理cookie全局緩存池
通常系統默認去管理這個對象,開發人員也能夠管理(加載的時機由系統控制)
管理身份驗證信息
2個子類
NSInternetPassword: 用戶名和密碼驗證
NSClientCertificate: 證書驗證
iOS 2 的時候推出的網絡接口(iOS 9廢除),接口比較少,實現了簡單的功能,暫停,斷點續傳,監聽進度等等的功能,自能開發人員本身去實現。
由上圖咱們能夠知道NSURLConnection
發送網絡請求的工做流程:
NSURLRequest
對象被傳遞給NSURLConnection
對象.NSURLConnection
在NSURLCache
裏邊找,若是有直接返回NSURLResponse
.NSHTTPCookieStorage
裏的cookie 和 NSURLCredentialStorage
裏的身份驗證信息,發送網絡請求NSURLProtocol
的代理裏邊獲得NSURLResponse
網絡請求配置,包括會話類型,緩存,超時時間,緩存,cookie,認證配置
//會話類型爲下邊的3種
//默認會話類型,可以進行磁盤緩存
//他們使用永久性的基於磁盤的緩存並將憑證存儲在用戶的鑰匙串
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
//臨時會話類型,不進行任何的磁盤緩存
//全部的緩存,憑證存儲等都保存在RAM中並與會話綁定。所以,當您的應用程序使會話失效時,它們會自動清除
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
//後臺類型,用於後臺下載上傳
//與默認會話相似,不一樣之處在於單獨的進程處理全部數據傳輸
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier;
//後臺會話配置的標識符
@property (nullable, readonly, copy) NSString *identifier;
//超時時間
@property NSTimeInterval timeoutIntervalForRequest;
//ServiceType
@property NSURLRequestNetworkServiceType networkServiceType;
//是否使用流量
@property BOOL allowsCellularAccess;
//cookie 配置
@property NSHTTPCookieAcceptPolicy HTTPCookieAcceptPolicy;
@property (nullable, retain) NSHTTPCookieStorage *HTTPCookieStorage;
//緩存配置
@property NSURLRequestCachePolicy requestCachePolicy;
@property (nullable, retain) NSURLCache *URLCache;
//認證配置
@property (nullable, retain) NSURLCredentialStorage *URLCredentialStorage;
複製代碼
NSURLSessionTask
有2個子類,繼承關係以下圖
NSURLSessionTask
是一個抽象類,若是要使用那麼只能使用它的子類。
NSURLSessionDataTask
能夠用來處理通常的網絡請求,如 GET | POST 請求等。
NSURLSessionDataTask
有一個子類爲 NSURLSessionUploadTask,用於處理上傳請求的時候有優點。
NSURLSessionDownloadTask
主要用於處理下載請求,有很大的優點。
NSURLConnection
的升級版本,功能比前者強大太多,也支持Http的更高的版本,傳輸速度更快。
@interface NSURLSession : NSObject
/* sharedSession屬性表示使用當前的全局的NSURLCache, NSHTTPCookieStorage 和 NSURLCredentialStorage對象。 */
@property (class, readonly, strong) NSURLSession *sharedSession;
/* * 構建方法 */
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
//操做隊列
@property (readonly, retain) NSOperationQueue *delegateQueue;
//代理
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
//配置
@property (readonly, copy) NSURLSessionConfiguration *configuration;
/* * 能夠提供對session 的標籤描述 */
@property (nullable, copy) NSString *sessionDescription;
/* 當即返回,現有任務將被容許運行完成。 新任務可能沒法建立。 會話將繼續進行代理的回調,直到發佈URLSession:didBecomeInvalidWithError:爲止。 finishTasksAndInvalidate 和 invalidateAndCancel 對共享會話單例沒有任何影響. 當使後臺會話無效時,在URLSession:didBecomeInvalidWithError:已經發布以前,使用相同的標識符建立另外一個後臺會話是不安全的。 */
- (void)finishTasksAndInvalidate;
/* 充當 finishTasksAndInvalidate,可是會針對此會話的全部未完成任務執行取消 cancel。 */
- (void)invalidateAndCancel;
- (void)resetWithCompletionHandler:(void (^)(void))completionHandler; /* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue if not nil. */
- (void)flushWithCompletionHandler:(void (^)(void))completionHandler; /* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue if not nil. */
- (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler; /* invokes completionHandler with outstanding data, upload and download tasks. */
- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); /* invokes completionHandler with all outstanding tasks. */
/* * NSURLSessionTask objects are always created in a suspended state and * must be sent the -resume message before they will execute. */
// NSURLSessionTask對象必須在暫停狀態下建立,必須發送- resume消息才執行。
/* 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. */
// 建立數據任務以檢索給定URL的內容
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
/* Creates an upload task with the given request. The body of the request will be created from the file referenced by fileURL */
// 根據給定的請求建立一個給定的上傳任務,請求體根據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. */
// 根據給定的請求,建立一個上傳任務,請求體根據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. */
// 根據給定的請求建立上傳任務,忽略之前請求的體流設置,當須要加載體的時候,
// 將會調用URLSession:task:needNewBodyStream: 代理方法。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
/* Creates a download task with the given request. */
// 根據指定的請求建立下載任務
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
/* Creates a download task to download the contents of the given URL. */
// 建立下載任務,下載給定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. */
// 根據resume data建立一個下載任務,若是下載不能成功開始,那麼會調用URLSession:task:didCompleteWithError:
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
/* Creates a bidirectional stream task to a given host and port. */
// 建立給定主機和端口的雙向流任務
- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
/* Creates a bidirectional stream task with an NSNetService to identify the endpoint. * The NSNetService will be resolved before any IO completes. */
// 使用NSNetService識別端點以建立雙向流任務。
// NSNetService將在任何IO完成以後解決
- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
複製代碼
分類 NSURLSessionAsynchronousConvenience
// NSURLSession便捷例程將結果傳遞給完成處理程序塊。 這些便利例程不適用於配置爲後臺會話的NSURLSessions。
// 任務對象老是在掛起狀態建立,而且必須在執行以前發送-resume消息。
@interface NSURLSession (NSURLSessionAsynchronousConvenience)
/* * 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. */
// 數據任務的便利方法。 這些方法建立繞過普通代理調用進行響應和數據傳遞的任務,
// 並提供一個簡單的可取消異步接口來接收數據。 錯誤將在NSURLErrorDomain中返回,
// 請參閱<Foundation / NSURLError.h>。 代理(若是有的話)仍將被要求認證挑戰。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
/* * upload convenience method. */
// 上傳任務便利化方法
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))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. */
// 下載任務便利化方法,當成功下載完成時,URL指向一個文件,
// 這個文件必須在完成調用中進行讀和賦值,文件將被自動移除。
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
@end
複製代碼
那麼怎麼理解這3個類呢? URLSession
是負責發送和接收請求的關鍵對象, URLSessionConfiguration
是URLSession
的配置參數,能夠經過URLSessionConfiguration
來建立URLSession
;而URLSessionTask
是一次任務(會話),他是URLSession
的具體執行者。下圖能夠看到:
NSURLRequest
URLCache
NSHTTPCookieStorage
NSURLCredentialStorage
這些基本類來處理。NSURLSession
均可以單獨配置 URLSessionConfiguration
NSURLConnection
使用異步回調,先將數據下載到內存,等下載完畢後,再寫入沙盒.若是文件很大,會致使內存暴漲; 而且,使用異步回調沒法監聽下載進度.因此使用 NSURLConnection
下載的時候,使用代理回調監聽下載進度,而且下載過程當中要手動管理內存(致使內存暴漲)
,使用起來比較麻煩.而使用NSURLSession
的時候,block
和代理能夠同時起做用,而且能夠直接從文件系統上傳、下載,不會出現內存暴漲的狀況. 下載文件的時候,默認會將文件下載到沙盒的 tmp文件夾中,不會佔多少用內存. 可是在下載完成後,會刪除文件,因此要在下載完成或者其餘須要的地方,增長保存文件的代碼.NSURLConnection
實例化對象,實例化開始,默認請求就發送(同步發送),不須要調用start
方法。而cancel
能夠中止請求的發送,中止後不能繼續訪問,須要建立新的請求。NSURLSession
有三個控制請求的方法,取消(cancel
),暫停(suspend
),繼續(resume
),暫停後能夠經過繼續恢復當前的請求任務。NSURLConnection
進行斷點下載,經過設置訪問請求的HTTPHeaderField
的Range
屬性,開啓運行循環,NSURLConnection
的代理方法做爲運行循環的事件源,接收到下載數據時代理方法就會持續調用,並使用NSOutputStream
(或者經過文件指針)管道流進行數據保存。NSURLSession
進行斷點下載,當暫停下載任務後,若是 downloadTask
(下載任務)爲非空,調用cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
這個方法,這個方法接收一個參數,完成處理代碼塊,這個代碼塊有一個NSData
參數 resumeData
,若是resumeData
非空,咱們就保存這個對象到視圖控制器的resumeData
屬性中。在點擊再次下載時,經過調用 [ [self.session downloadTaskWithResumeData: self.resumeData]resume]
方法進行繼續下載操做。通過以上比較能夠發現,使用NSURLSession
進行斷點下載更加便捷。NSURLSession
能夠設置配置信息 NSURLSession
的構造方法 (sessionWithConfiguration: delegate:delegateQueue
)中有一個 NSURLSessionConfiguration類的參數能夠設置配置信息,其決定了cookie
,安全和高速緩存策略,最大主機鏈接數,資源管理,網絡超時等配置。NSURLConnection
不能進行這個配置,相比於NSURLConnection
依賴於一個全局的配置對象,缺少靈活性而言,NSURLSession 有很大的改進了。 NSURLSession
能夠設置三種配置信息,分別經過調用三個類方法返回配置對象: +(NSURLSessionConfiguration *) defaultSessionConfiguration
,配置信息使用基於硬盤的持久化Cache
,保存用戶的證書到鑰匙串,使用共享cookie
存儲; +(NSURLSessionConfiguration *)ephemeralSessionConfiguration
配置信息和default
大體相同。除了,不會把cache
,證書,或者任何和Session
相關的數據存儲到硬盤,而是存儲在內存中,生命週期和Session
一致。好比瀏覽器無痕瀏覽等功能就能夠基於這個來作; +(NSURLSessionConfiguration *) backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
配置信息能夠建立一個能夠在後臺甚至APP已經關閉的時候仍然在傳輸數據的session
。 注意,後臺Session
必定要在建立的時候賦予一個惟一的identifier
,這樣在APP下次運行的時候,可以根據identifier
來進行相關的區分。若是用戶關閉了APP,IOS 系統會關閉全部的background Session
。並且,被用戶強制關閉了之後,IOS系統不會主動喚醒APP,只有用戶下次啓動了APP,數據傳輸纔會繼續。參考文章:
www.jianshu.com/p/2d4d1d7df…
www.cnblogs.com/1018475062q…
cloud.tencent.com/developer/a…
www.jianshu.com/p/877dec053…