最近在做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就可以很容易地實現這個功能。
上文已經講到了,在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,其中的參數有如下意義:
值得說明的時候,在初始化之後其實沒有任何變化,因為這個時候的默認模式是NORMAL_MODE,即跟NSURLCache是一樣的。所以感覺不出什麼不一樣。不要著急,很快我們就需要使用到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請求資源都會下載到我們的自定義目錄了。
好了,現在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以下吧,萬分感謝!