Objective-C: AFHTTPRequestOperationManager で結果キャッシュを無効にする

Objective-C iOS

とある iOS アプリから Web API と HTTP を喋るのに AFNetworking(2系)を利用しています。

AFNetworking というよりかは NSURLRequest の仕様だと思うのですが、下記のようなコードで、一度 HTTP リクエストを送った URL に対して 2 回目のリクエストを送るとクライアント側のキャッシュからデータ(レスポンス)を読むようです。
(サーバー側のレスポンスヘッダーが悪いような感じではなかった、、、)
このような場合、特に Web API などはクライアント依存になってしまう状態だと何かと不便です。

下記コードが問題のところ。
いたって普通の HTTP 通信するためのコードです。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:URL
  parameters:PARAMS
     success:^(AFHTTPRequestOperation *operation, id responseObject) {
        // anything
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // anything
     }];

どうにか解消できないかと調べていると、HTTP リクエストを送る際にキャッシュポリシーのオプションを指定できることがわかりました。
(公式ドキュメント - NSURLRequestCachePolicy - Foundation | Apple Developer Documentation

キャッシュポリシーは列挙型 NSURLRequestCachePolicy で、デフォルトが HTTP に従うようです。

下記コードが改善版。
[manager.requestSerializer setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData] が改善箇所です。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setCachePolicy: NSURLRequestReloadIgnoringLocalCacheData]
[manager GET:URL
  parameters:PARAMS
     success:^(AFHTTPRequestOperation *operation, id responseObject) {
        // anything
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // anything
     }];

なるほどなるほど。

他にどんなキャッシュポリシーがあるか調べました。

NSURLRequestCachePolicy (Objective-C) の種類

説明
NSURLRequestUseProtocolCachePolicy 基本的にはプロトコルのキャッシュ方針に従う。でも何故かキャッシュされっ放しのケースがある。プロパティに何も指定がなかった場合にデフォルトで設定される。
NSURLRequestReloadIgnoringLocalCacheData 必ずサーバー側にリクエストを送る。サーバー側のキャッシュコントロールには従う。
NSURLRequestReloadIgnoringLocalAndRemoteCacheData クライアント側、サーバー側ともにキャッシュを無視する。ただしサーバー側でプロキシーキャッシュしている場合はその限りではない。
NSURLRequestReturnCacheDataElseLoad クライアント側にキャッシュがあれば必ずキャッシュデータを返す。ちなみに未実装…。
NSURLRequestReloadRevalidatingCacheData サーバー側にキャッシュデータの妥当性を問い合わせた上でキャッシュを使うくさい。ちなみにこれも未実装…orz

いまさらの Objective-C ですが、書き方に癖があるだけで、今のところ自然に入り込めている感じ。

参考 URL

Objective-C iOS