iOS請求緩存、離線緩存 框架 ZBNetworking

  • 在最初接觸數(shù)據(jù)緩存的時候 就看到多個博客提到可以用SDWebImage緩存圖片方式的思路去做數(shù)據(jù)緩存渗鬼,可是基本沒有看到去實踐的览露,而更多看到的使用sqlite的封裝FMDB去做緩存,也有用系統(tǒng)的NSURLCache譬胎,可表現(xiàn)的都很難擴展差牛,對請求緩存中的一些操作都很單一。也許我沒看到好的吧堰乔,如果有請留言給我謝謝偏化。
  • 先說說一些緩存中的 誤區(qū):看到很多剛接觸緩存這塊的開發(fā)者認為 網(wǎng)絡狀態(tài)是緩存的第一判斷條件,大概是有網(wǎng)絡就重新請求數(shù)據(jù)浩考,無網(wǎng)絡就使用緩存夹孔。這么認為的就是進入誤區(qū)了。就說一個例子析孽,有網(wǎng)絡搭伤,但服務器掛了,怎么辦袜瞬。顯示你返回請求失敗的異常頁面嗎怜俐?有人說了 請求失敗再使用緩存唄。咱們做APP的 是不是要考慮用戶的使用體驗啊邓尤。請求失敗了拍鲤,都啥時候了贴谎,黃花菜都涼了。
  • 大家可以看看幾個主流APP 的緩存顯示方式“ 網(wǎng)易新聞”,“今日頭條”,“ 微博” 季稳。在有緩存的狀態(tài)下擅这, 這幾款APP都是 優(yōu)先顯示緩存,同時有的進行自動下拉刷新操作景鼠,有的給你提示仲翎,有多少條數(shù)據(jù)更新,請進行下拉刷新操作 铛漓。下拉刷新就是重現(xiàn)請求溯香,請求的結果有很多狀態(tài),與界面操作有關就幾種浓恶,請求成功替換顯示的數(shù)據(jù)玫坛,請求超時給提示,請求失敗給提示包晰∈疲可以看出 緩存是和請求分不開的(由于GET請求一般用來查詢數(shù)據(jù),POST請求一般是發(fā)大量數(shù)據(jù)給服務器處理(變動性比較大)因此一般只對GET請求進行緩存杜窄,而不對POST請求進行緩存)肠骆。
  • 正確的緩存的使用策略 是在有緩存的狀態(tài)下,使用緩存塞耕,沒有緩存去請求,請求的成功后的數(shù)據(jù)刷新界面嘴瓤,并覆蓋原緩存文件扫外。結合網(wǎng)絡請求,還要給出不使用緩存的狀態(tài)廓脆,和使用緩存的狀態(tài).在實際運用中可以能還有別的需求筛谚,比如上拉加載的狀態(tài),離線緩存的狀態(tài)停忿,所以請求的種類多樣驾讲,緩存的使用策略的狀態(tài)也要多樣。
  • 根據(jù)此緩存策略 封裝的 請求框架 ZBNetworking

ZBNetworking

優(yōu)點:
1.請求類型豐富/ * GET請求 // * POST請求 // * PUT請求 // * PATCH請求 // * DELETE請求 // * 上傳請求 // * 下載請求 /
2.低耦合席赂,易擴展吮铭。
3.通過Block配置信息,代碼緊湊;
4.有緩存文件過期機制默認一周
5.顯示緩存大小/個數(shù)颅停,全部清除緩存/單個文件清除緩存/按時間清除緩存/按路徑清除緩存方法多樣并且都可以自定義路徑可擴展性強
6.有緩存鍵過濾功能
7.離線下載功能
8.多種請求緩存類型的判斷谓晌。也可不遵循,自由隨你定癞揉。

    /** 重新請求 ,不讀取緩存纸肉,重新請求*/
    ZBRequestTypeRefresh,
    /** 有緩存,讀取緩存 無緩存溺欧,重新請求*/
    ZBRequestTypeCache,
    /** 加載更多 ,不讀取緩存,重新請求*/
    ZBRequestTypeRefreshMore,
    /** 加載更多 ,有緩存,讀取緩存 無緩存柏肪,重新請求*/
    ZBRequestTypeCacheMore,
    /** 詳情    ,有緩存,讀取緩存 無緩存姐刁,重新請求*/
    ZBRequestTypeDetailCache,
    /** 自定義  ,有緩存,讀取緩存 無緩存,重新請求*/
    ZBRequestTypeCustomCache

9.可見的緩存文件


ZBNetworking_cache_gif.gif

AFNetworking 不多介紹了 在使用OC開發(fā)的烦味,很多都用這個聂使。封裝了一個緩存管理類ZBCacheManager,主要參照了SDWebImage的SDImageCache磁盤存儲的思路,SDWebImage的存儲性能大家應該不用懷疑拐叉,但也要進行大量的改動岩遗,畢竟SDImageCache 只是緩存圖片的。不管用那種請求方法 緩存文件都會存儲到沙盒 /Library/Caches/ZBKit/AppCache 路徑下 凤瘦。
有一點要注意宿礁,請求下來的數(shù)據(jù)格式 是二進制的 因為緩存也是二進制數(shù)據(jù) 。所以設置了responseSerializer = [AFHTTPResponseSerializer serializer];不能更改蔬芥。

  • 運行流程如下圖
F0C2D948-9691-40B5-8251-554FB85A84EA.png

請求示例 具體看demo 梆靖。
2017-8-21 重構了此庫 現(xiàn)在默認為Refresh (重新請求,不讀緩存)笔诵。

[ZBRequestManager requestWithConfig:^(ZBURLRequest *request){
        request.urlString=list_URL;
        request.methodType=ZBMethodTypeGET;//默認為GET
        request.apiType=ZBRequestTypeCache;//默認為ZBRequestTypeRefresh
    }  success:^(id responseObj,apiType type){
        if (type==ZBRequestTypeRefresh) {
              //下拉結束刷新
        }  
        if (type==ZBRequestTypeLoadMore) {
            // 上拉結束刷新
        }
             //請求成功
        
    } failed:^(NSError *error){
        if (error.code==NSURLErrorCancelled)return;
        if (error.code==NSURLErrorTimedOut){
            [self alertTitle:@"請求超時" andMessage:@""];
        }else{
            [self alertTitle:@"請求失敗" andMessage:@""];
        }
    }];

//取消對應的網(wǎng)絡請求
 [ZBRequestManager cancelRequest: list_URL completion:^(NSString *urlString){
        //如果請求成功 或 讀緩存 會返回null 無法取消返吻。請求未完成的會取消并返回對應url
        //NSLog(@"取消對應url:%@ ",urlString);
    }];
  • 其他的一些功能 顯示緩存大小 ,緩存?zhèn)€數(shù)。按時間清除緩存乎婿,手動清理緩存测僵,自定義清除某個路徑文件,清除某個單獨key的緩存等功能谢翎,


    9075F331-0F70-44B8-8405-E067D1EE0A28.png

離線緩存/下載

  • 下面要說離線緩存功能捍靠。不知道該功能的:可以下個今日頭條/我的 /離線 功能看看 一般新聞類的APP 大多有該功能。
    要做離線緩存功能:必須要有先決條件森逮,就是一定不要多個緩存路徑 榨婆,特別是圖片的緩存功能,存儲路徑要統(tǒng)一褒侧。我的demo中圖片請求現(xiàn)在使用的是SDWebImage良风,其實也可以用別的(如YYWebImage)。只要你用的圖片請求框架 在數(shù)據(jù)列表顯示的圖片 和 在離線下載 的圖片 用的是一個緩存就可以闷供,SDWebImage 因為用了MD5編碼烟央,確保了每個URL對應的緩存唯一性。這里有個問題这吻,有很多應用有輪播視圖的功能 吊档,而大多數(shù)封裝好輪播都是自己進行請求并緩存到自定義的緩存路徑,這個要處理一下唾糯,最好統(tǒng)一為一個圖片請求框架怠硼,緩存路徑也就一樣了鬼贱。
C2A147C7-8F29-490F-82CE-62810491A150.png

好了 我們的列表圖片包括輪播圖片 緩存 都在SDWebImage 的默認緩存路徑里了,
而我們的json 數(shù)據(jù) 已經(jīng)緩存到/Library/Caches/ZBKit/AppCache 路徑下 香璃。下面開始 實現(xiàn)離線功能

  • 其實離線緩存并不是一個 高深的技術这难,還是緩存。正常我們?yōu)g覽一個頁面緩存這個頁面的數(shù)據(jù)葡秒。而離線就是同時請求多個頁面并緩存下來姻乓。


    F7B3FE2C-FE73-4D9E-A394-104C22FAA391.png

思路就是 每個頻道就是一個url,把你要緩存的 url 放到一個數(shù)組里 進行遍歷請求。ZBRequestManager已經(jīng)封裝好了 離線的方法

- (void)requestOffline:(NSMutableArray *)offlineArray{

    [ZBRequestManager sendBatchRequest:^(ZBBatchRequest *batchRequest){
         for (NSString *urlString in offlineArray) {
            ZBURLRequest *request=[[ZBURLRequest alloc]init];
            request.urlString=urlString;
            [batchRequest.urlArray addObject:request];
        }
    }  success:^(id responseObj,apiType type){

            NSLog(@"添加了幾個url請求  就會走幾遍");
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObj options:NSJSONReadingMutableContainers error:nil];
            NSArray *array=[dict objectForKey:@"videos"];
            for (NSDictionary *dic in array) {
                DetailsModel *model=[[DetailsModel alloc]init];
                model.thumb=[dic objectForKey:@"thumb"]; //找到圖片的key
                [self.imageArray addObject:model];
                
                //使用SDWebImage 下載圖片
                BOOL isKey=[[SDImageCache sharedImageCache]diskImageExistsWithKey:model.thumb];
                if (isKey) {
                    self.offlineView.progressLabel.text=@"已經(jīng)下載了";
                } else{
                    
                    [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:model.thumb] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize){
                        
                        NSLog(@"%@",[self progressStrWithSize:(double)receivedSize/expectedSize]);
                        
                        self.offlineView.progressLabel.text=[self progressStrWithSize:(double)receivedSize/expectedSize];
                        
                        self.offlineView.pv.progress =(double)receivedSize/expectedSize;
                        
                    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,BOOL finished,NSURL *imageURL){
                        
                        NSLog(@"單個圖片下載完成");
                        self.offlineView.progressLabel.text=nil;
                        
                        self.offlineView.progressLabel.text=[self progressStrWithSize:0.0];
                        
                        self.offlineView.pv.progress = 0.0;
                        
                        [self.tableView reloadData];
                        //讓 下載的url與模型的最后一個比較眯牧,如果相同證明下載完畢蹋岩。
                        NSString *imageURLStr = [imageURL absoluteString];
                        NSString *lastImage=[NSString stringWithFormat:@"%@",((DetailsModel *)[self.imageArray lastObject]).thumb];
                        
                        if ([imageURLStr isEqualToString:lastImage]) {
                            NSLog(@"下載完成");
                            
                            [self.offlineView hide];//取消下載進度視圖
                            [self alertTitle:@"下載完成"andMessage:@""];
                             self.imageArray=nil;
                        }
                        
                        if (error) {
                            NSLog(@"下載失敗");
                        }
                    }];
                    
                }
                
            }

    } failed:^(NSError *error){
        if (error.code==NSURLErrorCancelled)return;
        if (error.code==NSURLErrorTimedOut){
            [self alertTitle:@"請求超時" andMessage:@""];
        }else{
            [self alertTitle:@"請求失敗" andMessage:@""];
        }
    }];
}
cache

點擊 Github地址 下載

結尾:水平有限,代碼也很爛学少,一直在努力學習中剪个,大家多多包涵。如果你喜歡這個輪子版确,請給個star扣囊,這是對作者最大的鼓勵和支持,拜謝H蘖啤G中!假如你有更好的想法或方案請留言吓蘑!

下篇文章:設計一個簡單的圖片緩存器

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惕虑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子磨镶,更是在濱河造成了極大的恐慌枷遂,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棋嘲,死亡現(xiàn)場離奇詭異,居然都是意外死亡矩桂,警方通過查閱死者的電腦和手機沸移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侄榴,“玉大人雹锣,你說我怎么就攤上這事●希” “怎么了蕊爵?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桦山。 經(jīng)常有香客問我攒射,道長醋旦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任会放,我火速辦了婚禮饲齐,結果婚禮上,老公的妹妹穿的比我還像新娘咧最。我一直安慰自己捂人,他們只是感情好,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布矢沿。 她就那樣靜靜地躺著滥搭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捣鲸。 梳的紋絲不亂的頭發(fā)上瑟匆,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音摄狱,去河邊找鬼脓诡。 笑死,一個胖子當著我的面吹牛媒役,可吹牛的內(nèi)容都是我干的祝谚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酣衷,長吁一口氣:“原來是場噩夢啊……” “哼交惯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起穿仪,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤席爽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后啊片,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體只锻,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年紫谷,在試婚紗的時候發(fā)現(xiàn)自己被綠了齐饮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡笤昨,死狀恐怖祖驱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瞒窒,我是刑警寧澤捺僻,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響匕坯,放射性物質(zhì)發(fā)生泄漏束昵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一醒颖、第九天 我趴在偏房一處隱蔽的房頂上張望妻怎。 院中可真熱鬧,春花似錦泞歉、人聲如沸逼侦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽榛丢。三九已至,卻和暖如春挺庞,著一層夾襖步出監(jiān)牢的瞬間晰赞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工选侨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掖鱼,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓援制,卻偏偏與公主長得像戏挡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晨仑,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理褐墅,服務發(fā)現(xiàn),斷路器洪己,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評論 25 707
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫妥凳、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,098評論 4 62
  • 生活答捕、工作中逝钥,誰都會遇上與別人起沖突的糟心事兒。有的人拱镐,選擇以暴力的方式強行解決晌缘,槍桿子底下出政權就是這個思...
    諪諪_0c2f閱讀 159評論 0 0
  • 6.18四個力量 1.回顧筆的原理:兒子上午選擇一起外出又不想耽誤下午兩點的和朋友的打球!不能安住當下痢站,焦慮!我看...
    閃光的種子閱讀 261評論 0 0