新しいNSURLSessionでは、セッションの作成に使用されるNSURLSessionConfigurationオブジェクトにtimeoutIntervalForRequestがあります。
ただし、NSURLRequestオブジェクトには、セッションでNSURLSessionTaskを作成するために使用できるtimeoutIntervalがまだあります。
私の質問は、構成のtimeoutIntervalForRequestが30に設定されているが、タスクの作成に使用するNSURLRequestのtimeoutIntervalが60の場合、実際に使用されるタイムアウト間隔はどれですか?
IOS 7.0.3での私の調査によると、timeoutInterval
のNSURLRequest
は、NSURLSession
と一緒に使用しても効果がありません。
timeoutIntervalForRequest
をNSURLSessionConfiguration
に設定するかどうかに関係なく、timeoutInterval
は無視されます。
この動作を確認するには、私の小さなサンプルアプリケーション NetworkTimeoutSample を使用できます。
timeoutInterval
のNSURLRequest
に影響する「URLReq」フィールドに1を設定し、「NSURLSession With URLRequest」ボタンをクリックすると、セッションでタイムアウトエラーが発生しません。
timeoutIntervalForResource
のtimeoutIntervalForRequest
に対して同じタイムアウト効果を取得したい場合は、NSURLSession
に対してtimeoutInterval
の代わりにNSURLRequest
を設定する必要があることも認識できます。 var] _。
timeoutIntervalForRequest
にtimeoutIntervalForResource
とNSURLSessionConfiguration
の両方の値を設定すると、小さい値が影響を受けます(この動作は現在のAPIドキュメントとは異なると思います)。
これらの仕様に関するドキュメントはないため、将来のiOSバージョンで変更される可能性があります。
IOS8以降、サーバーが応答しない場合、バックグラウンドモードのNSUrlSessionはこのデリゲートメソッドを呼び出しません。 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
ダウンロード/アップロードは無期限にアイドル状態のままです。このデリゲートは、サーバーが応答しないときにエラーでiOS7で呼び出されます。
一般に、NSURLSessionバックグラウンドセッションは、ネットワーク上で問題が発生してもタスクを失敗させません。むしろ、リクエストを実行するのに適した時間を探し続け、その時点で再試行します。これは、リソースのタイムアウトが期限切れになるまで続きます(つまり、セッションの作成に使用するNSURLSessionConfigurationオブジェクトのtimeoutIntervalForResourceプロパティの値)。その値の現在のデフォルトは1週間です。つまり、iOS7でタイムアウトに失敗する動作は正しくありませんでした。バックグラウンドセッションのコンテキストでは、ネットワークの問題が原因ですぐに失敗しない方が興味深いです。そのため、iOS8以降、NSURLSessionタスクは、タイムアウトやネットワーク損失が発生した場合でも続行されます。ただし、timeoutIntervalForResourceに達するまで続行されます。
したがって、基本的にtimeoutIntervalForRequestはバックグラウンドセッションでは機能しませんが、timeoutIntervalForResourceは機能します。
Apple 開発者フォーラム のスタッフ)のメンバーの1人からこの回答を得ました。また、実装してこれを確認しました。
N-miyoがテストしてから状況が変わったようです。
Appleのドキュメント は、NSURLRequest値がセッション構成を上書きすると述べています。
場合によっては、この構成で定義されたポリシーが、タスクに提供されたNSURLRequestオブジェクトによって指定されたポリシーによってオーバーライドされることがあります。セッションのポリシーがより制限されていない限り、リクエストオブジェクトで指定されたポリシーはすべて尊重されます。たとえば、セッション構成でセルラーネットワークを許可しないように指定されている場合、NSURLRequestオブジェクトはセルラーネットワークを要求できません。
NSURLSession
は、timeoutIntervalForRequest
とtimeoutIntervalForResource
の2つのタイムアウトを提供します。
timeoutIntervalForRequest
は、データが転送されるたびにリセットされるタイマーによって適用されます。したがって、このタイムアウトを30秒に設定し、少なくとも1バイトのデータが30秒ごとに転送される場合、タイムアウトに達することはありません。タイムアウトが発生するのは、30秒間データがまったく転送されない場合のみです。これは、セッションタスクの最大アイドル時間であるとも言えます。デフォルト値は60秒です。
timeoutIntervalForResource
は、リセットされないタイマーによって強制されます。セッションタスクが開始されると開始され、セッションタスクが停止または終了すると停止します。つまり、これはセッションタスクにかかる最大合計時間であり、ほとんどの人が「タイムアウト」と聞いたときに考えます。セッションタスクは、非常に遅いインターネットリンクを介した100 GBファイルのダウンロードでもある可能性があるため、ここでのデフォルト値は7日です。
NSURLRequest
(およびその可変サブクラス)は、1つのプロパティtimeoutInterval
のみを提供します。このタイムアウト値は、timeoutIntervalForRequest
のドキュメントにあるように、NSURLRequest
のように動作します。
接続の試行中に、要求がタイムアウト間隔より長くアイドル状態のままである場合、要求はタイムアウトしたと見なされます。
ソース: timeoutInterval --NSURLRequest | Apple開発者向けドキュメント
そして、NSURLSession
のドキュメントには次のように書かれています。
注
場合によっては、この構成で定義されたポリシーが、タスクに提供されたNSURLRequestオブジェクトによって指定されたポリシーによってオーバーライドされることがあります。セッションのポリシーがより制限されていない限り、リクエストオブジェクトで指定されたポリシーはすべて尊重されます。
ソース: NSURLSessionConfiguration-Foundation | Apple Developer Documentation
したがって、timeoutInterval
のNSURLRequest
はtimeoutIntervalForRequest
のNSURLSession
を上書きしますが、それ以外の場合は、システムによって「より制限的」であると見なされます。 NSURLSession
の値が優先されます。