在開發閱讀類 App 時,實現「文章離線閱讀」是剛需:需將網頁所有資源(HTML、圖片、JS、CSS 等)一次性下載到本地。系統自帶的 NSURLCache 不支持自定義存儲目錄,本文介紹一個經過實戰驗證、兼容 iOS 8+ 的開源方案 —— CustomURLCache,並詳細講解接入全流程。
CustomURLCache 提供兩種運行模式,靈活適配不同場景:
| 模式 | 行為 | 適用場景 |
|---|---|---|
| NORMAL_MODE | 行為與系統 NSURLCache 一致 | 普通瀏覽、無需離線 |
| DOWNLOAD_MODE | 攔截請求並將響應存入自定義目錄,支持過期時間 | 進入文章詳情頁,啟用離線下載 |
iOS 8 規定必須在 application:didFinishLaunchingWithOptions: 中設置共享緩存才生效:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 初始化:內存 20MB、磁盤 200MB、默認路徑、永不過期
CustomURLCache *cache = [[CustomURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024
diskCapacity:200 * 1024 * 1024
diskPath:nil
cacheTime:0
subDirectory:nil];
[NSURLCache setSharedURLCache:cache];
return YES;
}
參數說明:
diskPath:nil 時自動使用 App 沙盒 Caches 目錄cacheTime:0 表示永不過期,單位秒subDirectory:初始化時傳 nil,具體子目錄在切換模式時指定在文章頁 UIViewController 的 init 或 initWithNibName:bundle: 中啟用下載模式:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_mCache = (CustomURLCache *)[NSURLCache sharedURLCache];
[_mCache changeToDownloadMode:_subDir]; // _subDir 為該文章唯一子目錄
[NSURLCache setSharedURLCache:_mCache];
}
return self;
}
此後所有 UIWebView 發起的請求,響應會自動保存到 diskPath/_subDir/ 下。
在 dealloc 或自定義返回方法中:
- (void)backToMainpage:(id)sender {
if (不再需要文章緩存) {
NSLog(@"刪除文章緩存");
[_mCache removeCustomRequestDictionary]; // 刪除該子目錄所有緩存
}
[_mCache changeToNormalMode]; // 切回系統默認行為
[self.navigationController popViewControllerAnimated:YES];
}
再次進入同一文章時,changeToDownloadMode: 會先檢查本地緩存:
這實現了「首次聯網、二次極速」的離線閱讀體驗。
代碼已開源托管於 GitHub,歡迎 Star、Fork、提 Issue: