NSURLConnectionにおいてタイムアウトは無視される(こともある)

久々にiOSプログラミングの記事書くよ。

POSTを使ってデータを同期通信で送信するには

みたいなことをを書けばいいというのは以前書いたのだけど、ここで、タイムアウトを設定するには
– setTimeoutInterval:
関数を使えばいいと思うよね。ところがどっこい。ここにとんでもない落とし穴が。

これで動かしてみると、コンソールにはこう表示される。

つまりどういうことかというと、設定したタイムアウトは無視され強制的に240秒になります。どうもバグでなく仕様のようです。正直理解しがたい仕様です。
無視される条件には2つあります。

  • POSTメソッドを使っていること
  • BODYに値を設定していること

この2つの条件を満たし、BODYに値を設定した瞬間にタイムアウトは無視。

じゃ、どうすればいいかというと、まずGETメソッドを使うというのがある。しかし、セキュリティが保てないのよね。ということで、NSTimerを使って自分でタイムアウト処理を記述してしまおうというのがこのエントリの主題。

アプローチは2つあって、1つはNSThreadを使って別スレッドで同期通信の処理行い、メインスレッドの方でNSTimerを使って時間のカウントを行って時間が経過したら通信処理スレッドを終了してしまうという方法。もう一つは非同期通信を使って通信を行うようにして、NSTimerで時間をカウントして、時間経過で非同期通信を止めてしまうという方法。
何となく、後者の方がシンプルな気がしたので、後者を採用。

まず通信開始部分

ひとまずこんな感じ、ここだとタイムアウトを15秒で設定しています。
併せてタイムアウト時の処理も

あとは、非同期通信なのでNSURLConnectionのdelegateを実装すれば実装は終わりです。
正常に通信が完了した際(-(void)connectionDidFinishLoading:(NSURLConnection *)connection関数コール時)にも

を忘れないように。
こんな感じでNSTimerで簡単なタイムアウト処理を書けました。
タイムアウト無視の変な仕様が無ければこんな面倒臭いことしなくてもよかったんですがねぇ・・・

あ、急いでコード書いたのでろくにデバッグしてません、多分リークがあります。


コメントを残す