iOS URL Loading System

iOS URL Loading System包含如下:


官方文檔參考

本文主要介紹三個(gè)部分:NSURLProtocol莉兰、Cookie Storage、Cache Management革娄。

NSURLProtocol

NSURLProtocol參考鏈接
參考代碼(增加對WKWebView的支持)

NSURLCache 和 NSCachedURLResponse

說完NSURLProtocol擎宝,就到了緩存階段。
緩存管理類為對URL請求的回應(yīng)提供了緩存堡距。NSURLCache類為URL提供了通用緩存(這里注意,WKWebView從iOS9之后就有了WKWebsiteDataStore類來管理WKWebView http請求的緩存以及Cookie等)

  1. 調(diào)用[NSURLCache sharedURLCache]方法,默認(rèn)會創(chuàng)建緩存區(qū)([NSURLCache sharedURLCache].currentDiskUsage = 86016Byte羽戒,[NSURLCache sharedURLCache].currentMemoryUsage = 0缤沦,iOS5之后默認(rèn)是磁盤緩存),其中緩存區(qū)Memory capacity: 4 megabytes 易稠,Disk capacity: 20 megabytes
  2. 當(dāng)然我們也可以通過自定義的方式來實(shí)現(xiàn)是否緩存疚俱,感謝此鏈接
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    CusURLCache *cache = [[CusURLCache alloc] initWithMemoryCapacity:(2*1024*1024) diskCapacity:((100 * 1024 * 1024)) diskPath:nil];
    [CusURLCache setSharedURLCache:cache];
    return YES;
}

//  CusURLCache.h
//  Http測試
//
//  Created by XinWeizhou on 2017/4/28.
//  Copyright ? 2017年 XinWeizhou. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CusURLCache : NSURLCache

@end

#import "CusURLCache.h"

@implementation CusURLCache
// CusURLCache告訴系統(tǒng)我有怎樣的已緩存的NSCachedURLResponse對象(或者沒有)缩多,這里攔截了http://img1.gtimg.com/news/pics/hv1/138/183/2205/143426928.jpeg呆奕,并且做了假的NSURLResponse以供緩存
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    
    NSURL *url = [request URL];
    NSLog(@"request.string = %@",request.URL.absoluteString);
    if ([url.absoluteString isEqualToString:@"http://img1.gtimg.com/news/pics/hv1/138/183/2205/143426928.jpeg"]) {
        
        NSLog(@"request = %@",request);
        
        NSURLResponse *response =
        [[NSURLResponse alloc] initWithURL:url
                                  MIMEType:@"text/plain"
                     expectedContentLength:1
                          textEncodingName:nil];
        NSCachedURLResponse *cachedResponse =
        [[NSCachedURLResponse alloc] initWithResponse:response
                                                 data:[NSData dataWithBytes:" " length:1]];
         // 有人可能會認(rèn)為只需要返回假的響應(yīng)對象就夠了,沒必要緩存它衬吆。但這樣會因響應(yīng)對象被系統(tǒng)釋放而導(dǎo)致app crash梁钾。不知道為何為會這樣,可能是iOS的bug(Mac OS X 10.5.x也存在同樣問題逊抡,而10.4.x及更早的系統(tǒng)上沒有問題)姆泻,也可能是URL Loading System內(nèi)部類之間的依賴所致。                                        
        [super storeCachedResponse:cachedResponse forRequest:request];
    }
    
    return [super cachedResponseForRequest:request];
   
}

- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request {
    NSLog(@"request2 = %@ === response2 = %@",request,cachedResponse);
    [super storeCachedResponse:cachedResponse forRequest:request];
}

說明:NSURLCache 將對每一個(gè)NSURLRequest對象遵守緩存策略(NSURLRequestCachePolicy)冒嫡,策略如下所示:
1. NSURLRequestUseProtocolCachePolicy 默認(rèn)的緩存策略拇勃,對特定的URL請求使用網(wǎng)絡(luò)協(xié)議中實(shí)現(xiàn)的緩存邏輯
2. NSURLRequestReloadIgnoringLocalCacheData 忽略本地緩存,重新請請求
3. NSURLRequestReloadIgnoringLocalAndRemoteCacheData 忽略本地和遠(yuǎn)程緩存孝凌,重新請求(未實(shí)現(xiàn))
4. NSURLRequestReturnCacheDataElseLoad 有緩存則從中加載方咆,如果沒有則去請求
5. NSURLRequestReturnCacheDataDontLoad 無網(wǎng)絡(luò)狀態(tài)下不去請求,一直加載本地緩存數(shù)據(jù)無論其是否存在
6. NSURLRequestReloadRevalidatingCacheData 默從原始地址確認(rèn)緩存數(shù)據(jù)的合法性之后蟀架,緩存數(shù)據(jù)才可使用瓣赂,否則請求原始地址(未實(shí)現(xiàn))

注意:NSURLCache緩存不緩存request及response,不是由request得緩存策略決定的片拍,緩存策略只是說明是否加載已經(jīng)存在的緩存煌集,緩存機(jī)制有URL Loading System提供。

Cookie Storage

現(xiàn)在談?wù)刪ttpCookie相關(guān):NSHTTPCookie和NSHTTPCookieStorage捌省。(這里注意苫纤,WKWebView從iOS9之后就有了WKWebsiteDataStore類來管理WKWebView http請求的緩存以及Cookie等)

  1. cookie和NSURLRequest的關(guān)系,除非NSURLRequest明確指定不使用cookie(HTTPShouldHandleCookies設(shè)為NO),否則URL loading
    system會自動(dòng)為NSURLRequest發(fā)送合適的存儲cookie纲缓。

  2. NSHTTPCookieStorage:從NSURLResponse返回的cookie也會根據(jù)NSHTTPCookieStorage的cookie訪問策略(cookie acceptance policy)接收到系統(tǒng)中卷拘。

    通過NSHTTPCookieStorage可讀取/修改cookie接收策略,默認(rèn)為NSHTTPCookieAcceptPolicyAlways.

    -(NSHTTPCookieAcceptPolicy)cookieAcceptPolicy;

    -(void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.

    一共有三種cookie accept policy色徘。typedef enum {
    NSHTTPCookieAcceptPolicyAlways,
    NSHTTPCookieAcceptPolicyNever,
    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
    } NSHTTPCookieAcceptPolicy;

    NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默認(rèn)策略.

  3. NSHTTPCookieStorage通知

    當(dāng)NSHTTPCookieStorage實(shí)例中的cookies變化時(shí)發(fā)出此通知
    NSHTTPCookieManagerCookiesChangedNotification

    當(dāng)NSHTTPCookieStorage實(shí)例的cookie acceptance policy變化時(shí)發(fā)出此通知
    NSHTTPCookieManagerAcceptPolicyChangedNotification

  4. NSHTTPCookie

    使用NSHTTPCookie的類方法可以將NSHTTPCookie實(shí)例與HTTP headerField相互轉(zhuǎn)換:

// 從響應(yīng)頭獲取Cookie信息:
 + (NSArray *)cookiesWithResponseHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)theURL;
// 手動(dòng)cookie創(chuàng)建例子:
   NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];  // 創(chuàng)建cookie屬性字典
   [cookieProperties setObject:@"username" forKey:NSHTTPCookieName]; // 手動(dòng)設(shè)置cookie的屬性
   [cookieProperties setObject:@"Boat" forKey:NSHTTPCookieValue];
   [cookieProperties setObject:@"yzwind.com" forKey:NSHTTPCookieDomain];
   [cookieProperties setObject:@"www.yzwind.com" forKey:NSHTTPCookieOriginURL];
   [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
   [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
   NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];  
 // 用Cookie設(shè)置請求頭:
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:@[cookie]];
// 請求頭這里只設(shè)置了Cookie
request.allHTTPHeaderFields = headers;
打印結(jié)果
headers = {
   Cookie = "username = Boat";
}
// 直接給請求頭設(shè)置Cookie:
[request setValue:"username = Boat" forHTTPHeaderField:@"Cookie"];  

NSHTTPCookie Class Reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恭金,一起剝皮案震驚了整個(gè)濱河市操禀,隨后出現(xiàn)的幾起案子褂策,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斤寂,死亡現(xiàn)場離奇詭異耿焊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)遍搞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門罗侯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人溪猿,你說我怎么就攤上這事钩杰。” “怎么了诊县?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵讲弄,是天一觀的道長。 經(jīng)常有香客問我依痊,道長避除,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任胸嘁,我火速辦了婚禮瓶摆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘性宏。我一直安慰自己群井,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布毫胜。 她就那樣靜靜地躺著蝌借,像睡著了一般。 火紅的嫁衣襯著肌膚如雪指蚁。 梳的紋絲不亂的頭發(fā)上菩佑,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音凝化,去河邊找鬼稍坯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搓劫,可吹牛的內(nèi)容都是我干的瞧哟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼枪向,長吁一口氣:“原來是場噩夢啊……” “哼勤揩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起秘蛔,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤陨亡,失蹤者是張志新(化名)和其女友劉穎傍衡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體负蠕,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛙埂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遮糖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绣的。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖欲账,靈堂內(nèi)的尸體忽然破棺而出屡江,到底是詐尸還是另有隱情,我是刑警寧澤赛不,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布盼理,位于F島的核電站,受9級特大地震影響俄删,放射性物質(zhì)發(fā)生泄漏宏怔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一畴椰、第九天 我趴在偏房一處隱蔽的房頂上張望臊诊。 院中可真熱鬧,春花似錦斜脂、人聲如沸抓艳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玷或。三九已至,卻和暖如春片任,著一層夾襖步出監(jiān)牢的瞬間偏友,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工对供, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留位他,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓产场,卻偏偏與公主長得像鹅髓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子京景,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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