程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Objective-c下具有下載功能的NSURLCache類CustomURLCache

Objective-c下具有下載功能的NSURLCache類CustomURLCache

編輯:關於C語言

Objective-c下具有下載功能的NSURLCache類CustomURLCache


最近在做iOS APP開發的過程中遇到了這麼一個問題:我開發的是一個閱讀類的App,正文界面是通過UIWebViewController來實現的,現在要實現文章離線閱讀功能。即將當前web頁面所有的資源請求結果都下載都本地。在網上找了很多方法,發現都不是很好。後來還是決定從cache入手:iOS自帶的NSURLCache並不支持將cache下載到自定義的目錄底下,所以只有復寫NSURLCache這個類來實現這些功能。在網上找到一個他人寫的CustomURLCache的類,但是發現使用的過程中程序會崩,於是一步一步調試代碼,定位到該類的錯誤,對代碼進行了修改,修復了這個bug。而隨著iOS8的推出,發現設置自定義的URLCache必須要在AppDelegate.m的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 函數中使用才行,否則無效。無奈,只好進一步對代碼進行修改。終於可以適配ios8了。今天將這部分代碼分享出來,希望對大家有用。代碼我已經托管到github上,大家可以自行下載。

同時為了兼容系統NSURLCache的功能,CustomURLCache有兩種模式,NORMAL_MODE和DOWNLOAD_MODE,NORMALMODE下的CustomCache和NSURLCache的功能是一樣的;而DOWNLOADMODE下的CustomURLCache則可以實現包含自定義下載目錄,設置過期時間的子功能的下載功能。

接下來用例子教大家如何使用CustomURLCache這個類。假設我們在做一個閱讀類的App,正文頁面用UIWebViewController來展示。現在需要實現一個離線下載的功能,即將當前網頁的所有訪問到的資源(html文件,圖片,JavaScript,CSS等等)全部都保存到本地。用CustomURLCache就可以很容易地實現這個功能。

在AppDelegate.m中將CustomURLCache設置為全局URLCache

上文已經講到了,在iOS8中,設置全局URLCache必須在AppDelegate.m中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions實現,所以第一步就是將我們CustomURLCache在該函數中設置為全局URLCache:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    ......
    //Init custom cache
    
    CustomURLCache *_mCache = [[CustomURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024
                                                diskCapacity:200 * 1024 * 1024
                                                    diskPath:nil
                                                   cacheTime:0
                                                subDirectory:nil];
    [NSURLCache setSharedURLCache:_mCache];

    return YES;
}

這段代碼將我們的CustomURLCache設置為了全局的URLCache,其中的參數有如下意義:

  • diskCapacity:就是用戶設置的這個cache的大小
  • diskPath:cache的下載路徑,如果設置為nil的話,那麼該類將會自動將當前應用的緩存目錄作為下載路徑
  • cacheTime:cache的過期時間,如果設置為0的話,那麼cache將永遠不會過期
  • subDirectory:這是位於diskPath下的子目錄,意為當前的cache會存在哪個子目錄中。不過在初始化的時候只用將其設置為nil即可

    值得說明的時候,在初始化之後其實沒有任何變化,因為這個時候的默認模式是NORMAL_MODE,即跟NSURLCache是一樣的。所以感覺不出什麼不一樣。不要著急,很快我們就需要使用到DOWNLOAD_MODE了。

    將CustomURLCache設置為DOWNLOAD_MODE

    好了,假設我們在第一個頁面選中了一篇文章,然後點擊計入了正文頁面,正文頁面的布局很簡單,就是一個UIWebView,我們需要用其顯示一個網頁,並且將所有需要請求的資源都下載到本地自定義的目錄中。這個時候就需要用到DOWNLOAD_MODE了。實現很簡單,在正文界面的UIViewController的- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil或者init函數中將CustomURLCache設置為DOWNLOAD_MODE:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            
            ......
    
        
            _mCache = (CustomURLCache *)[NSURLCache sharedURLCache];
            [_mCache changeToDownloadMode:_subDir];
            [NSURLCache setSharedURLCache:_mCache];
        }
        return self;
    }

    現在我們就成功地將CustomURLCache設置為了下載模式,在執行[_mCache changeToDownloadMode:_subDir];時需要指定下載子目錄,就位於diskPath下的下載子目錄。接下來所有的web請求資源都會下載到我們的自定義目錄了。

    將CustomURLCache恢復到NORMAL_MODE

    好了,現在web頁面也展現出來了,所有的web請求資源都下載到本地了,該退出了。回退到第一個頁面,並且不再需要DOWNLOAD_MODE,我們要將其恢復為NORMAL_MODE,那麼在當前UIViewController下的dealloc函數或者其他用戶自定義的退出函數中加入如下代碼(在這裡我使用的是自己的退出函數):

    - (void)backToMainpage:(id)sender {
        if (不再需要文章緩存) {
            NSLog(@"刪除文章緩存");
            [_mCache removeCustomRequestDictionary ];  
        }
        else
        {
        //do nothing
         }
        //不再使用自定義緩存,而是換到系統的緩存
        [_mCache changeToNormalMode];
        [self.navigationController popViewControllerAnimated:YES];
    }

    好了,如果你沒有刪除文章緩存,那麼當我們再次就如正文頁面的時候,你會發現頁面很快就加在完成了。原因很簡單,當你再次進入該UIViewController的時候,程序又會執行[_mCache changeToDownloadMode:_subDir];這時,CustomURLCache在接到URL請求的時候會先到_subDir路徑下去找是否有緩存的資源,如果找到了,並且還不過期,那麼就會自動加在本地的資源,如果沒有找到或者過期了,那麼會重新通過網絡請求。所以你知道為什麼這麼快就完成了,因為所有的資源都是在本地的!

    好了,簡單地使用就介紹到這裡了。希望對大家有幫助。同時,如果大家喜歡的話就請在GitHub上fork或者star以下吧,萬分感謝!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved