網(wǎng)絡(luò)資源加載方式(一)

URLLoading System( 網(wǎng)絡(luò)資源加載)

Foundation框架中提供了資源網(wǎng)絡(luò)請(qǐng)求部分的基本組件,通過指定-URL(資源路徑)和TransformProtocol(傳輸協(xié)議),通過stream流實(shí)現(xiàn)數(shù)據(jù)的傳輸融欧。常見的傳輸協(xié)議主要有以下幾種:

*File Transfer Protocol (ftp://) 文件傳輸協(xié)議:常用作文件傳輸協(xié)議,公司內(nèi)部和局網(wǎng)內(nèi)常使用磨确。

*Hypertext Transfer Protocol (http://)超文本傳輸協(xié)議: 常用于瀏覽器中網(wǎng)絡(luò)請(qǐng)求

*Hypertext Transfer Protocol with encryption (https://)加密的超文本傳輸協(xié)議,就是在http的基礎(chǔ)上增加了C/S(服務(wù)器與客戶端)之間的認(rèn)證,

  • Local file URLs (file:///),本地資源傳輸協(xié)議,按照協(xié)議規(guī)定的格式從本地加載資源,其后指定的就是資源在本地的路徑,大家有沒有主意到這里有三條斜杠,因?yàn)樗械膮f(xié)議必須以 ://+ 主機(jī)地址或域名:端口號(hào) +/文件資源路徑或者是查詢語句。 此處是加載本地文件,所以中間的主機(jī)域名和端口號(hào)省略了就變成:///。

  • Data URLs (data://) 數(shù)據(jù)傳輸協(xié)議。

當(dāng)然除此之外你還可以定義自己的協(xié)議,比如蘋果的 sms:// 短信協(xié)議, prompt:// 庭惜,

  • 例如當(dāng)我門要與HTML5做交互的時(shí)候,可以通過定義我門自己的協(xié)議頭 ourselfprotocol://+你需要攔截信息。 不熟悉的朋友請(qǐng)看UIWebView頭文件的代理方法穗酥。 通過截獲協(xié)議頭的scheme,我們就能快速的定位那些是需要我門攔截分析的URL了,當(dāng)然你也可以通過字符串進(jìn)行分割护赊。

+URL加載系統(tǒng)包括類加載URL以及一些重要的助手類,使用這些URL加載類修改他們的行為惠遏。助手類主要分為五類:協(xié)議支持,認(rèn)證和證書,cookie存儲(chǔ)、配置管理和緩存管理骏啰。Foundation中主要提供了如下幾個(gè)類用于網(wǎng)絡(luò)資源的加載.包括目前的很多主流框架如SDWebImage,AFNetWroking,都依賴這些類节吮。主要常用的還是NSURLConnection,NSURLSession,NSURL,NSURLRequest.

資源加載協(xié)議類NSURLProtocol

 *從名字上很容易想到它是一個(gè)定義資源加載的協(xié)議,其實(shí)不然. 它屬于一個(gè)抽象的類判耕,定義了一些基本的方法,主要是機(jī)遇網(wǎng)絡(luò)請(qǐng)求資源加載的透绩。通常使用它的子類進(jìn)行擴(kuò)展,當(dāng)使用NSURLSession和NSURLConnection進(jìn)行網(wǎng)絡(luò)資源加載的時(shí)候,通常會(huì)去訪問NSURLClinetProtocol,即詢問請(qǐng)求方是否能夠處理這個(gè)請(qǐng)求,如果返回能則使用我門自定的子類進(jìn)行網(wǎng)絡(luò)資源加載,如果不能則使用系統(tǒng)默認(rèn)的方式進(jìn)行資源加載
//這是一個(gè)NSURLProtoclClient的對(duì)象,它就像一個(gè)鉤子 一樣,如果我們?nèi)绻贜SURLLoadingSystem詢問NSURlProtocol 的canInitWithRequest 方法時(shí)候,回答YES,則需要我們自己定義類去處理網(wǎng)絡(luò)請(qǐng)求,這個(gè)時(shí)候NSURLProtocolClient實(shí)例就是專門來幫我們處理網(wǎng)絡(luò)請(qǐng)求資源的回調(diào)的祈秕。之所以系統(tǒng)定義到這個(gè)類的屬性里,是為了我門在創(chuàng)建NSURLProtocol子類的時(shí)候,通過子類能夠狠方便的調(diào)用 NSURLProtocolClient的實(shí)例去處理網(wǎng)路資源的加載渺贤。
@property (nullable, readonly, retain) idclient;  
//一個(gè)請(qǐng)求對(duì)象的實(shí)例對(duì)象雏胃,將我門訪問的URL資源路徑,請(qǐng)求頭中的一些參數(shù)進(jìn)行了統(tǒng)一的封裝,如 accept type,Content-Type,文件的編碼格式,壓縮方式,是否保持心跳連接,是否適用Cookie,lastModify time请毛,服務(wù)器名稱,版本號(hào),協(xié)議版本號(hào),請(qǐng)求方式GET,POST,請(qǐng)求資源的長(zhǎng)度,常用的就只有accetpt type,Content-Type瞭亮,
@property (readonly, copy) NSURLRequest *request;  
//這個(gè)屬性從字面意思都能看得出來,就是緩存request 的響應(yīng)數(shù)據(jù)的,方便下次系統(tǒng)調(diào)用的時(shí)候直接獲取
@property (nullable, readonly, copy) NSCachedURLResponse *cachedResponse;
//這個(gè)屬性用到的比較多,系統(tǒng)在請(qǐng)求網(wǎng)絡(luò)資源或從定向的時(shí)候都會(huì)來詢問這個(gè)方法,如果回答是,則表示 使用用戶自定義的protocol來處理網(wǎng)絡(luò)資源的加載,如果我門需要使用離線加載,則需要將此方法進(jìn)行改寫方仿。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request; 
//這個(gè)方法相當(dāng)與事給我門需要進(jìn)行請(qǐng)求的Request對(duì)象的headerFields進(jìn)行重新設(shè)置,我門可以自定一請(qǐng)求頭,這樣我門可以通過request headerFields中的某些特定的屬性來過濾我門不需要處理的Request,讓她們直接采用NSURLLoadingSystem系統(tǒng)的方式進(jìn)行網(wǎng)絡(luò)資源的加載统翩。我門可以通過改寫系統(tǒng)這個(gè)方法,設(shè)置它的通用的請(qǐng)求頭仙蚜, 如 appKey :xxxx, userAgent: xxxx,version: ios Mobile
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;
//緩存專用API,判斷本地緩存中NSURLRequest對(duì)象和我門需要請(qǐng)求的NSURLRequest對(duì)象是否相同,如果是相通的 厂汗。委粉。。那么娶桦。贾节。。衷畦。
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b;
//開始進(jìn)行資源加載,這個(gè)方法執(zhí)行的前提是當(dāng)我門實(shí)現(xiàn)了
- (void)startLoading;
//停止加載
- (void)stopLoading; 

+(BOOL)CanInitWithRequet方法并返回YES后,并且使用+ (BOOL)registerClass:(Class)protocolClass注冊(cè)我門自定義的NSURLProtocol子類;才會(huì)執(zhí)行此方法,這就是前面說到的我門自己實(shí)現(xiàn)網(wǎng)絡(luò)資源的加載栗涂。

//下面幾個(gè)APi主要是對(duì)我門需要處理的NSURLRequest對(duì)象進(jìn)行處理,標(biāo)記那些已經(jīng)是請(qǐng)求過的,那些是沒有請(qǐng)求過的祈争。通過KVO的方式給它的headerFIelders添加一個(gè)參數(shù)進(jìn)行判定斤程。 
+ (nullable id)propertyForKey:(NSString *)key inRequest:(NSURLRequest *)request;
+ (void)setProperty:(id)value forKey:(NSString *)key inRequest:(NSMutableURLRequest *)request;

+ (void)removePropertyForKey:(NSString *)key inRequest:(NSMutableURLRequest *)request;

+ (BOOL)registerClass:(Class)protocolClass;

主要是為了配合我門在完成自定義的資源加載過程中的請(qǐng)求,我門只需要在實(shí)現(xiàn)的NSURLSession和NSURLConnection的代理方法中通過鉤子來實(shí)現(xiàn)這些方法就行了,將 URL資源加載成功,加載失敗,加載完成,重定向進(jìn)行重。這樣就保證的在我門自定義處理網(wǎng)絡(luò)資源加載后菩混,最后又將結(jié)果移交給了系統(tǒng)URLLoadingSystem處理忿墅。

NSURLProtocol子類的實(shí)例->URLLoadingSystem-》詢問NSURLProtocol canInitWithRequest-(是)》startLoading->調(diào)用NSURLSession/NSURLConnection進(jìn)行網(wǎng)絡(luò)資源請(qǐng)求-》在請(qǐng)求完成的代理方法中實(shí)現(xiàn)NSURLClientProtocol請(qǐng)求處理。-》注銷NSURLProtocol子類實(shí)例沮峡【纹辏總的來說系統(tǒng)自動(dòng)進(jìn)行URL資源加載->切換手動(dòng)資源加載-》加載結(jié)束切換系統(tǒng)進(jìn)行URL資源加載。而在手動(dòng)進(jìn)行資源加載過程中,這期間的request,response,redirectRequest帖烘,cache亮曹,data橄杨,error,所有的這些時(shí)間都由我門自己定義。 你只需要在子類重寫的canInitWithRequest方法中進(jìn)行攔截我門需要處理的請(qǐng)求進(jìn)行處理就可以了,甚至還可以對(duì)我門項(xiàng)目需要離線加載的頁面做一個(gè)專門的配置文件表照卦,在此方法類的每次請(qǐng)求的URLRequest對(duì)象做一個(gè)判定式矫,然后再進(jìn)行處理。

//下面為NSURLClient的實(shí)現(xiàn)方法,
- (void)URLProtocol:(NSURLProtocol *)protocol wasRedirectedToRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse;


```objective-c 
//截獲重定向的URL請(qǐng)求頭,確定是否響應(yīng)役耕。
- (void)URLProtocol:(NSURLProtocol *)protocol cachedResponseIsValid:(NSCachedURLResponse *)cachedResponse;
//緩存是否有效
- (void)URLProtocol:(NSURLProtocol *)protocol didReceiveResponse:(NSURLResponse *)response cacheStoragePolicy:(NSURLCacheStoragePolicy)policy;
//設(shè)置Request的緩存策略,由于我門是自定義子類,如果你需要完成自定義的離線緩存采转,那么此方法類需要適用設(shè)置為NSURLCacheStoreagePolicy為NO。
- (void)URLProtocol:(NSURLProtocol *)protocol didLoadData:(NSData *)data;
//此方法與NSURLSession didReceiveData 或者NSURLConnection didReceviveData一起使用,將接收到的數(shù)據(jù)返回給NSURLLoadingSystem(系統(tǒng)資源加載系統(tǒng)).這樣才不會(huì)影響我門在其他的類文件里調(diào)用網(wǎng)絡(luò)請(qǐng)求方法獲取數(shù)據(jù)瞬痘。
- (void)URLProtocolDidFinishLoading:(NSURLProtocol *)protocol;
- (void)URLProtocol:(NSURLProtocol *)protocol didFailWithError:(NSError *)error;
- (void)URLProtocol:(NSURLProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

*自己對(duì)請(qǐng)求的授權(quán)挑戰(zhàn)進(jìn)行處理, 因?yàn)槲议T自定義子類,主要是做離線緩存,或者設(shè)定Request請(qǐng)求頭的一些規(guī)則,以及重定向之類的. 此處你也可以為指定的一些https的請(qǐng)求做一些特殊的處理故慈。

*首先需要拿到challenge的保護(hù)空間,獲取到服務(wù)器的受信任對(duì)象,serverTrust,其實(shí)就是一個(gè)證書憑證,不過現(xiàn)在通過stream流傳輸過來被系統(tǒng)封裝成了一對(duì)象。 如果這個(gè)對(duì)象是

- (void)URLProtocol:(NSURLProtocol *)protocol didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末框全,一起剝皮案震驚了整個(gè)濱河市察绷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌津辩,老刑警劉巖拆撼,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異喘沿,居然都是意外死亡闸度,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門蚜印,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莺禁,“玉大人,你說我怎么就攤上這事窄赋∮炊” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寝凌,是天一觀的道長(zhǎng)柒傻。 經(jīng)常有香客問我,道長(zhǎng)较木,這世上最難降的妖魔是什么红符? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮伐债,結(jié)果婚禮上预侯,老公的妹妹穿的比我還像新娘。我一直安慰自己峰锁,他們只是感情好萎馅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著虹蒋,像睡著了一般糜芳。 火紅的嫁衣襯著肌膚如雪飒货。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天峭竣,我揣著相機(jī)與錄音塘辅,去河邊找鬼。 笑死皆撩,一個(gè)胖子當(dāng)著我的面吹牛扣墩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扛吞,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼呻惕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了滥比?” 一聲冷哼從身側(cè)響起亚脆,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎守呜,沒想到半個(gè)月后型酥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡查乒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了郁竟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玛迄。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖棚亩,靈堂內(nèi)的尸體忽然破棺而出蓖议,到底是詐尸還是另有隱情,我是刑警寧澤讥蟆,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布勒虾,位于F島的核電站,受9級(jí)特大地震影響瘸彤,放射性物質(zhì)發(fā)生泄漏修然。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一质况、第九天 我趴在偏房一處隱蔽的房頂上張望愕宋。 院中可真熱鬧,春花似錦结榄、人聲如沸中贝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邻寿。三九已至蝎土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绣否,已是汗流浹背瘟则。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枝秤,地道東北人醋拧。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像淀弹,于是被迫代替她去往敵國(guó)和親丹壕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在薇溃,面了一些公司菌赖,掛了不少,但最終還是拿到小米沐序、百度琉用、阿里、京東策幼、新浪邑时、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評(píng)論 11 349
  • iOS網(wǎng)絡(luò)編程讀書筆記 Facade Tester客戶端門面模式的實(shí)例(被動(dòng)版本化) 被動(dòng)版本化特姐,所以硬編碼URL...
    melouverrr閱讀 1,606評(píng)論 3 7
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理晶丘,服務(wù)發(fā)現(xiàn),斷路器唐含,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,102評(píng)論 25 707
  • 說一件事 前幾天的 下雨捷枯。 從新華書店回學(xué)校的2路公交車上滚秩,忘記哪一站了。 上來一個(gè)頭發(fā)花白的老爺爺淮捆,個(gè)子很高很高...
    蜻蜓隊(duì)長(zhǎng)的pen閱讀 609評(píng)論 0 0