關(guān)于ios的cookie,可能很多人都并不太了解,因?yàn)閕os內(nèi)部已經(jīng)幫我們封裝好了,只要是NSURLRequest的請(qǐng)求,ios內(nèi)部會(huì)默認(rèn)幫我們保存服務(wù)器返回的cookie并保存在sandbox下,但是具體是怎么進(jìn)行保存的呢,我在今天的項(xiàng)目里發(fā)現(xiàn)了一個(gè)問(wèn)題。
今天在做項(xiàng)目的時(shí)候,本來(lái)的項(xiàng)目需求是在登錄之后,在主頁(yè)面獲取用戶信息,但是退出app,下次登錄的時(shí)候,用戶就不需要登錄,可以直接獲取到信息,所以我就在登錄之前調(diào)用獲取信息的接口,第一次登錄的時(shí)候,因?yàn)闆](méi)有登錄,所以調(diào)用獲取信息的接口顯示的是401,沒(méi)有授權(quán),當(dāng)你第一次登錄成功的時(shí)候,ios會(huì)幫你保存登錄成功后后臺(tái)給你返回的cookie,所以下次登錄之前調(diào)用獲取信息的接口,默認(rèn)會(huì)幫你帶上之前保存的cookie,這樣就不需要登錄并且獲取信息成功,從而判斷是現(xiàn)實(shí)登錄頁(yè)面還是主頁(yè)(一般登錄的cookie會(huì)保存30天,之后就會(huì)提示用戶需要登錄)。
然而在這中間,我也發(fā)現(xiàn)了一些問(wèn)題,在你登錄成功到主頁(yè)面后,迅速的commond+r 重新運(yùn)行項(xiàng)目,這個(gè)時(shí)候,你依然是獲取不到用戶信息的,顯示的還是401未授權(quán)。這時(shí)候我就奇怪了,明明登錄成功,內(nèi)部幫我保存了cookie,并且在sandbox下也有cookie的文件,怎么會(huì)獲取不了數(shù)據(jù)呢,然后我就做了以下的實(shí)驗(yàn)。
首先在appDelegate中打印沙河路徑
然后打印本地的cookie
然后調(diào)用獲取數(shù)據(jù)的接口
運(yùn)行程序后,進(jìn)入沙河文件夾
然后打印本地cookie為空(因?yàn)榈谝淮未蜷_(kāi)程序,本地并沒(méi)有緩存cookie)
接著調(diào)用獲取數(shù)據(jù)的接口,顯示的是401未授權(quán)
然后過(guò)了大概5,6秒,sandbox就會(huì)自動(dòng)多一個(gè)Cookies的文件夾,顯示大小為236字節(jié),這應(yīng)該就是內(nèi)部自動(dòng)幫我們進(jìn)行的cookie保存,并在下一次調(diào)用接口的自動(dòng)帶上cookie
然后回到主頁(yè)調(diào)用接口的時(shí)候在成功回調(diào)里打印后臺(tái)給我們返回的cookie,這個(gè)時(shí)候是可以獲取到數(shù)據(jù)的,并且返回了rememberMe和sid兩條cookie
在獲取到數(shù)據(jù)的時(shí)候我就立刻command+r,重新運(yùn)行程序,按道理說(shuō)在appDelegate中調(diào)用獲取數(shù)據(jù)接口的時(shí)候會(huì)自動(dòng)帶上cookie,應(yīng)該是可以獲取到數(shù)據(jù)的,但是并不是這樣,依然顯示401沒(méi)有授權(quán),并且打印本地的cookie只有一條sid,那rememberMe怎么不見(jiàn)了?
然后我就繼續(xù)試了幾次,結(jié)果依舊是這樣
本地依舊只有sid這個(gè)cookie
后來(lái)我意識(shí)到可能是系統(tǒng)內(nèi)部存儲(chǔ)cookie是需要一定時(shí)間的,于是下一次登錄成功后我沒(méi)有立刻重新運(yùn)行程序,而是在停留了7,8秒后再重新運(yùn)行,這個(gè)時(shí)候才發(fā)現(xiàn)sandbox里面的Cookies文件夾的大小變大了,之前的236字節(jié)變成844字節(jié)了!
然后在appDelegate中打印的本地cookie也恢復(fù)正常了
并且之后調(diào)用接口也能正常獲取到數(shù)據(jù)了!
總結(jié)一下,系統(tǒng)會(huì)自動(dòng)幫你獲取cookie并本地保存,但是這是需要一定時(shí)間的(具體是為什么我也不清楚),但是這種情況會(huì)導(dǎo)致你的項(xiàng)目會(huì)出現(xiàn)一定的bug,因?yàn)楫?dāng)你的用戶會(huì)出現(xiàn)登錄后不在app內(nèi)停留而立刻退出的情況,這樣的話,可能過(guò)幾個(gè)小時(shí)后再次打開(kāi)的話又需要登錄(一般的app一次登錄后在一個(gè)月內(nèi)是不需要再次登錄的),這樣就很影響用戶體驗(yàn)。
而針對(duì)這樣的情況,我們可以在后臺(tái)返回的cookie時(shí)自己手動(dòng)將cookie保存,并在appDelegate上手動(dòng)取出來(lái),這樣就可以解決問(wèn)題了!
NSData* cookiesData = [NSKeyedArchiverarchivedDataWithRootObject: [[NSHTTPCookieStoragesharedHTTPCookieStorage]cookies]];
NSUserDefaults* defaults = [NSUserDefaultsstandardUserDefaults];
[defaultssetObject: cookiesDataforKey:@"kCookie"];
[defaultssynchronize];