web-dev-qa-db-ja.com

NSURLSessionConfigurationtimeoutIntervalForRequestとNSURLSessiontimeoutInterval

新しいNSURLSessionでは、セッションの作成に使用されるNSURLSessionConfigurationオブジェクトにtimeoutIntervalForRequestがあります。

ただし、NSURLRequestオブジェクトには、セッションでNSURLSessionTaskを作成するために使用できるtimeoutIntervalがまだあります。

私の質問は、構成のtimeoutIntervalForRequestが30に設定されているが、タスクの作成に使用するNSURLRequestのtimeoutIntervalが60の場合、実際に使用されるタイムアウト間隔はどれですか?

22
Joe Licari

IOS 7.0.3での私の調査によると、timeoutIntervalNSURLRequestは、NSURLSessionと一緒に使用しても効果がありません。

timeoutIntervalForRequestNSURLSessionConfigurationに設定するかどうかに関係なく、timeoutIntervalは無視されます。

この動作を確認するには、私の小さなサンプルアプリケーション NetworkTimeoutSample を使用できます。

timeoutIntervalNSURLRequestに影響する「URLReq」フィールドに1を設定し、「NSURLSession With URLRequest」ボタンをクリックすると、セッションでタイムアウトエラーが発生しません。

timeoutIntervalForResourcetimeoutIntervalForRequestに対して同じタイムアウト効果を取得したい場合は、NSURLSessionに対してtimeoutIntervalの代わりにNSURLRequestを設定する必要があることも認識できます。 var] _。

timeoutIntervalForRequesttimeoutIntervalForResourceNSURLSessionConfigurationの両方の値を設定すると、小さい値が影響を受けます(この動作は現在のAPIドキュメントとは異なると思います)。

これらの仕様に関するドキュメントはないため、将来のiOSバージョンで変更される可能性があります。

19
n-miyo

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人からこの回答を得ました。また、実装してこれを確認しました。

5
Utsav Dusad

N-miyoがテストしてから状況が変わったようです。

Appleのドキュメント は、NSURLRequest値がセッション構成を上書きすると述べています。

場合によっては、この構成で定義されたポリシーが、タスクに提供されたNSURLRequestオブジェクトによって指定されたポリシーによってオーバーライドされることがあります。セッションのポリシーがより制限されていない限り、リクエストオブジェクトで指定されたポリシーはすべて尊重されます。たとえば、セッション構成でセルラーネットワークを許可しないように指定されている場合、NSURLRequestオブジェクトはセルラーネットワークを要求できません。

2
Zeev Vax

NSURLSessionは、timeoutIntervalForRequesttimeoutIntervalForResourceの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

したがって、timeoutIntervalNSURLRequesttimeoutIntervalForRequestNSURLSessionを上書きしますが、それ以外の場合は、システムによって「より制限的」であると見なされます。 NSURLSessionの値が優先されます。

1
Mecki