Objective-C: AFHTTPRequestOperationManager で結果キャッシュを無効にする
とある 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 ですが、書き方に癖があるだけで、今のところ自然に入り込めている感じ。