URL加載系統(tǒng)是一組類和協(xié)議的集合,它允許我們的App訪問URL指定的內(nèi)容的。
URL加載系統(tǒng)的核心類是NSURL,該類提供了大量方法讓我們操作URLs和它指向的資源。另外它還提供了一系列的類來加載URL的內(nèi)容,上傳數(shù)據(jù)到服務(wù)器,管理Cookie存儲,控制響應(yīng)緩存,處理認(rèn)證存儲和授權(quán)信息,及自定義協(xié)議擴(kuò)展。
URL Loading System可支持以下協(xié)議
file://
data://
另外它還支持代理服務(wù)和網(wǎng)關(guān)處理。
URL加載系統(tǒng)定義了用于加載URL的類,另外還定義了一些輔助類來修改加載類的行為。這些輔助類可以分為五大類:
協(xié)議支持
授權(quán)與認(rèn)證
Cookie存儲
配置管理
緩存管理
整個(gè)URL加載系統(tǒng)的結(jié)構(gòu)如下圖所示:

URL Loading
在這張圖中,我們用得最多的就是URL Loading中的這幾個(gè)類。這些類允許我們從URL指定的源獲取內(nèi)容。根據(jù)不同的需求,我們可以使用不同的類,這主要依賴于我們應(yīng)用所支持的系統(tǒng)版本,以及我們希望內(nèi)容是以文件的形式獲取還是以數(shù)據(jù)塊的方式獲取。對于系統(tǒng)的版本,主要有以下幾點(diǎn)作為參考:
在iOS7及后續(xù)版本中,推薦使用NSURLSession。
對于iOS7以前的版本,可以使用NSURLConnection來獲取數(shù)據(jù)并加載到本地內(nèi)存中。如果要保存數(shù)據(jù),可以再將數(shù)據(jù)寫入磁盤。
而對于獲取數(shù)據(jù),主要看我們是獲取數(shù)據(jù)到內(nèi)存中還是下載文件并保存。如果只是獲取數(shù)據(jù)到內(nèi)存中,則有兩種方法:
對于簡單的請求,可以使用NSURLSession
對于復(fù)雜的請求(如上傳數(shù)據(jù)請求),提供了NSURLRequest對象來與NSURLSession和NSURLConnection一起使用。
不管使用哪種方法,我們都可以獲取到響應(yīng)數(shù)據(jù),為此,我們可以如下處理響應(yīng)
提供一個(gè)響應(yīng)處理block。當(dāng)URL Loading類完成從服務(wù)端接收數(shù)據(jù)時(shí)調(diào)用該block.
提供自定義有delegate。URL Loading類間斷性地調(diào)用我們的代理方法來獲取數(shù)據(jù)。在需要的情況下,我們的程序負(fù)責(zé)收集這些數(shù)據(jù)。
另外,URL Loading提供了一個(gè)返回對象來封裝與請求相關(guān)的元數(shù)據(jù),如MIME類型等。
而如果我們需要下載文件,則有兩個(gè)基本方法來處理:
對于簡單請求,可以使用NSURLSession
對于復(fù)雜請求,提供了NSURLRequest對象來與NSURLSession和NSURLDownload一起使用。
相較于NSURLDownload,NSURLSession有兩個(gè)明顯的優(yōu)勢:NSURLSession可用于iOS系統(tǒng),而NSURLDownload在iOS中不被支持;當(dāng)應(yīng)用掛起、終止或異常退出時(shí),下載可以在后臺繼續(xù)進(jìn)行。
URL Loading中還提供了兩個(gè)類用于處理元數(shù)據(jù),一個(gè)用于表示客戶端請求(NSURLRequest),一個(gè)用于表示服務(wù)端響應(yīng)(NSURLResponse)。我們分別介紹一下這兩個(gè)類。
NSURLRequest
NSURLRequest對象封裝了URL和協(xié)議指定的屬性,及依賴于協(xié)議的行為。同時(shí)也指定了本地緩存策略及連接超時(shí)時(shí)間。一些協(xié)議支持協(xié)議指定的屬性,如HTTP協(xié)議可以添加返回HTTP請求體,請求報(bào)頭和傳輸方法到NSURLRequest中。
這里需要注意的是,當(dāng)我們使用NSURLRequest的子類NSMutableURLRequest初始化一個(gè)連接或下載時(shí),將會對NSMutableURLRequest實(shí)例進(jìn)行深拷貝。因此在初始的請求上做修改時(shí)不會影響到連接和下載對象。
NSURLResponse
一個(gè)響應(yīng)可以分為兩個(gè)部分:描述內(nèi)容的元數(shù)據(jù)和內(nèi)容數(shù)據(jù)本身。而NSURLResponse類封裝了大部分協(xié)議的響應(yīng)元數(shù)據(jù),這些元數(shù)據(jù)包括MIME類型,期望的Content-Length,編碼格式,及提供響應(yīng)的URL。NSURLResponse的一些子類提供了與協(xié)議相關(guān)的額外元數(shù)據(jù)。如NSHTTPURLResponse存儲了web服務(wù)器返回的響應(yīng)頭和狀態(tài)碼。
需要注意的是NSURLResponse對象只存儲響應(yīng)的元數(shù)據(jù),而不存儲響應(yīng)數(shù)據(jù)本身。響應(yīng)數(shù)據(jù)由URL Loading通過響應(yīng)處理block和對象的代理來接收并處理。
認(rèn)證和證書
針對認(rèn)證和證書,URL加載系統(tǒng)提供了以下幾個(gè)類:
NSURLCredential:封裝了由認(rèn)證信息和持久化行為組成的證書。
NSURLProtectionSpace:表示需要特定證書的區(qū)域。一個(gè)保護(hù)區(qū)域可以限制到單獨(dú)的URL,擁有web服務(wù)器的區(qū)域,或引用一個(gè)代理。
NSURLCredientialStorage:一般是一個(gè)共享實(shí)例,用于管理證書存儲和提供NSURLCredential對象到NSURLProductionSpace對象的映射。
NSURLAuthenticationChallenge:封裝了認(rèn)證一個(gè)請求的的NSURLProtocol實(shí)現(xiàn)所需要的信息:一個(gè)建議的證書、保護(hù)空間、錯(cuò)誤信息或者協(xié)議用于確定所需要認(rèn)證的響應(yīng)、以及認(rèn)證嘗試次數(shù)等。初始對象(即請求發(fā)送者)必須實(shí)現(xiàn)NSURLAuthenticationChallengeSender協(xié)議。NSURLAuthenticationChallenge實(shí)例被用于NSURLProtocol的子類來告訴URL加載系統(tǒng)需要認(rèn)證。他們同樣為NSURLConnection和NSURLDownload的代理方法提供了便利的自定義認(rèn)證處理。
緩存管理
URL加載系統(tǒng)提供基于磁盤和內(nèi)存的緩存,允許程序減少對網(wǎng)絡(luò)連接的依賴,并提供對緩存響應(yīng)的快速訪問。緩存存儲在每個(gè)app的緩存文件夾下。NSURLConnection會根據(jù)緩存策略(初始化NSURLRequest對象中指定的)來查詢緩存。
NSURLCache提供了配置緩存大小和磁盤存儲位置的方法。同時(shí)提供了包含緩存響應(yīng)的NSCacheURLResponse對象集合的方法。NSCacheURLResponse對象封裝了NSURLResponse對象和URL數(shù)據(jù),同時(shí)提供用戶信息字典,這些信息可以用于緩存任何用戶數(shù)據(jù)。
不是所有的協(xié)議實(shí)現(xiàn)都支持響應(yīng)緩存。當(dāng)前只有http和https請求可被緩存。
一個(gè)NSURLConnection對象可以通過connection:willCacheResponse:代理訪求來控制是否緩存響應(yīng),響應(yīng)是否只應(yīng)該存儲在內(nèi)存中。
Cookie存儲
由于HTTP協(xié)議是無狀態(tài)的,所以客戶端通常使用cookie來保存URL請求的數(shù)據(jù)。URL加載系統(tǒng)提供了接口來創(chuàng)建和管理cookie,將cookie作為HTTP請求的一部分來發(fā)送,及解析web服務(wù)端響應(yīng)數(shù)據(jù)時(shí)接收cookie.
iOS提供了NSHTTPCookieStorage類來管理一個(gè)NSHTTPCookie對象的集合。
協(xié)議支持
URL加載系統(tǒng)默認(rèn)支持http, https, file, ftp, data協(xié)議。另外,URL加載系統(tǒng)也允許我們注冊自己的類來支持額外的系統(tǒng)層級的網(wǎng)絡(luò)協(xié)議。我們也可以添加指定協(xié)議的屬性到URL請求和URL響應(yīng)對象