2012/09/20更新

[XCODE] UIWebViewでHTML,CSS,JSなどをキャッシュさせない方法

このエントリーをはてなブックマークに追加            

こんにちは、WebViewベースのアプリ開発中の@yoheiMuneです。
今日は、WebViewベースのアプリ開発で困る問題の一つ、JSやCSSがキャッシュされて変更内容が更新されないという問題に対応したいと思いブログを書きました。

画像



WebViewベースのアプリ作成時の課題

WebViewベースのアプリを作成している時に色々な課題にぶち当たります。 その中の一つに、WebViewがJSやCSSをキャッシュしてしまい、 コードを書き換えても反映されないという問題があり、最近はその問題に悩まされてます。

そこでWebViewがキャッシュしないようには出来ないものかと調べました。
その調査結果を纏めたのが、今回のブログ記事となります。一部情報は未検証な部分があります(これから検証します)。
そのため、不備などありましたらご指摘頂けると幸いです。

「キャッシュを禁止する」とはアプリの速度が落ちる事に直結します。今回の対策案はあくまで開発中に用いるものと認識頂けると幸いです。



UIWebViewでキャッシュを禁止する

キャッシュを禁止するには、以下3つのどれかを実施すれば出来そうです。

  1. キャッシュの容量をゼロにする(最初の1回のみで良い)
  2. 送信するリクエストのキャッシュポリシーをキャッシュ禁止にする。
  3. リクエスト送信の度にキャッシュを削除する。

以下ではそれぞれの対応方法を説明します。


1、キャッシュ容量をゼロにする

キャッシュ容量をゼロにすることで、キャッシュできない仕組みにしてしまいます。
以下の処理を行うことで容量ゼロにできます。この処理は、UIWebView起動時とかにやればいいかなと思います。
[[NSURLCache sharedURLCache] setMemoryCapacity:0];


2、送信するリクエストのキャッシュポリシーをキャッシュ禁止にする。

UIWebView内で、リンクなどでの画面遷移リクエストを補足する為に、UIWebViewDelegateを利用します。
以下のように、UIWebViewDelegateをUIWebViewに設定します。
// webViewは今回キャッシュ禁止にする対象のUIWebView。
// selfは、UIWebViewDelegateプロトコルの実装を宣言しておく。
webView = self;
そして、UIWebViewDelegateで定義された以下のメソッド内で、キャッシュ禁止の処理を書きます。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
}
このDelegateメソッドを用いることで、毎回のリクエストを拾うことが出来ます。

そして、上記で横取りしたRequestのキャッシュポリシーを変更します。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

  // どの環境でもダウンキャストが出来るかは不明。
  // そしてこれで本当にキャッシュポリシーが変更されているかは、検証しなきゃです。
 if (request.cachePolicy != NSURLRequestReloadIgnoringLocalCacheData) {
        
    NSMutableURLRequest *req = (NSMutableURLRequest *)request;
    req.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
  }

  return YES;
}

一応、これでキャッシュポリシーの上書きは出来たと思われます(たぶん)。
ちゃんと後日に検証します。
自分の環境では、明らかに読み込みが遅くなったので、キャッシュを使っていないように思われます。


3、リクエスト送信の度にキャッシュを削除する

以下の方法でもキャッシュされずにリクエストが出来そうです。
(ただし処理が重たくなりそうです)。
リクエストの開始時点のDelegateメソッドで、以下の処理を行います。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

  // キャッシュを削除する。
  [[NSURLCache sharedURLCache] removeAllCachedResponses];
}



最後に

これで正しいのかは少し不安ですが、一応開発中はあまり困らなくなりそうです。
もしかしたら、Cache容量をゼロにしたら、後続の処理は要らないかも。

あとリリースした後は、キャッシュを使いつつ、 サーバーから配信するJS,CSSがバージョンアップされたらキャッシュをクリアするような仕組みにしたいなぁと思っています。
これについてはこれから仕組みを考えます。

本ブログは未検証事項を含みますので、ご参照時にはご自身でも検証してみて下さい。
また不備があればご指摘頂けると幸いです。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。