Tech Racho エンジニアの「?」を「!」に。
  • 開発

[iOS/iPhone] NSURLConnectionの同期通信でタイムアウトを設定したい

NSURLConnectionを使う際、非同期通信を基本にすべきですが、反応速度が重要でない場合は同期でやってしまいたいこともあります。

ただし、sendSynchronousRequestを使うと、NSURLRequestで指定したtimeoutIntervalは無視されるようで、不正なURLを指定した場合などに強制的に30秒以上待たされます。

「同期通信で、タイムアウトを5秒くらいにしたラッパーを作りたい」と思い、非同期通信を行い、通信が完了するまでwhileループで待つようなことを試してみました。

response = nil; //responseはvolatile指定したインスタンス変数
[NSURLConnection connectionWithRequest:request delegate:self];
while (response == nil) {
    [NSThread sleepForTimeInterval:1]; //1行待ってみる
    NSLog(@"待っています・・・");
}

このようにして、データを受け取るconnectionメソッドでは、インスタンス変数responseに結果を格納するようにします。

・・・しかし、この方法では永久に「待っています・・・」と表示されて、いつまでたっても受信されません。

理由

理由は、connectionWithRequest自体は別スレッドで実行されるものの、その結果となるconnectionはメインスレッドで実行されるためです。
つまり、whileループのあるメソッドが終了するまで、プールに溜まるだけでconnectionメソッドが実行されないということみたいです。

また、connectionWithRequestそのものを別スレッドにする方法では、NSThreadjoinに相当するものが無いため、即座に親スレッドが終了し、connectionが呼ばれる前に子スレッドも終了されてしまいます。

残念ながら、pthreadjoinするような力業を使わない限り、「同期通信で、タイムアウトを5秒くらいにしたラッパーを作りたい」という目標は実現が難しそうです。

どなたか良い解決案をお持ちでしたら、是非教えて下さい。

そもそもtimeoutIntervalが無視されたり、joinが無いなどというのはライブラリの欠陥な気がするのですが・・・


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。