大きなデータのダウンロードなどは通信に時間がかかるので、ユーザの希望でその通信をキャンセルできるようにしたい。
HUD(Head Up Display)としてSVProgressHUD
を使っていることを前提としてメモしておく。
http://kevsaidwhat.blogspot.jp/2013/06/cancel-svprogresshud-process-by-tapping.html
仕様
ユーザの希望をどのようにアプリが受け取るか、ということについては
- ユーザがHUDをタップしたとき
とした。ユーザがHUDをタップすると、実行中のHTTP通信がキャンセルされて、HUDが消える。
SVProgressHUD
はタッチイベントを受け取ると、SVProgressHUDDidReceiveTouchEventNotification
通知を通知センターに送っているのでこれを利用する。
HUD表示時
キャンセル処理の実装クラスが通知を受け取れるように、オブザーバとして登録する。
- (void)someTask
{
//通信のトリガーとなる処理を実装する
//...
//HUDを表示させる前に、通知センターへオブザーバとして登録する
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hudTapped:) name:SVProgressHUDDidReceiveTouchEventNotification object:nil];
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
}
キャンセル通知受信時
HUDがタップされるとhudTapped:
が呼び出されるので、ここにキャンセルのための処理とHUDを消すための処理を実装する。キャンセル処理ができたらオブザーバ登録を解除する。
- (void)hudTapped:(NSNotification *)notification
{
//コネクタにキャンセルを依頼する
[self.connector cancelHTTPTask]; //この実装では、HTTP通信のタスクは`connector`オブジェクトに一任している
[[NSNotificationCenter defaultCenter] removeObserver:self name:SVProgressHUDDidReceiveTouchEventNotification object:nil];
[SVProgressHUD dismiss];
}
ところでcancelHTTPTask
の実装では、AFHTTPSessionManager
のサブクラスのインスタンスを使ってinvalidateSessionCancelingTasks:
を呼び出している。このメソッドが、AFNetworking(AFHTTPSessionManager)を使う際の通信タスクのキャンセル処理の本体となる。
注意点
キャンセル通知受信時に行っているオブザーバの解除は、HTTP通信が終了した際のブロック処理またはデリゲートにも実装しておく。