[iOS] timeoutIntervalForRequest 

URLSessionのタイムアウト時間は`timeoutIntervalForRequest`と`timeoutIntervalForResource`の2種類ある。

|プロパティ  |用途  |
|---|---|
|timeoutIntervalForRequest  |リクエストのタイムアウト  |
|timeoutIntervalForResource  |通信全体のタイムアウト  |

と思い込んでいたが、**実は違う。**  
`timeoutIntervalForRequest` はリクエストがサーバーに到達した後、サーバーレスポンスにかかる時間にも適用される。

# timeoutIntervalForRequestの公式説明

https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1408259-timeoutintervalforrequest

> The request timeout interval controls how long (in seconds) a task should wait for additional data to arrive before giving up. The timer associated with this value is reset whenever new data arrives. When the request timer reaches the specified interval without receiving any new data, it triggers a timeout.The default value is 60.

（自分訳）
リクエストタイムアウトインターバルは追加データの受信をギブアップする前にどれだけ長く待つか制御する。
この値に紐付けられたタイマーは新しいデータを受信するたびにリセットされる。
そのタイマーが新しいデータを受信せず設定されたインターバールに達した場合、タイムアウトが発生する。
デフォルト値は60

# timeoutIntervalForResourceの公式説明

https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1408153-timeoutintervalforresource

> The resource timeout interval controls how long (in seconds) to wait for an entire resource to transfer before giving up. The resource timer starts when the request is initiated and counts until either the request completes or this timeout interval is reached, whichever comes first.
The default value is 7 days.

（自分訳）
リソースタイムアウトインターバルは全リソースの転送をギブアップする前にどれだけ長く待つか制御する。
リソースタイマーはリクエストが開始されたときに開始され、リクエストが完了するかタイムアウトインターバルに到達するまで、どちらか先に来た方までカウントする。
デフォルト値は7日

# ネットの情報

## What's different between timeoutIntervalForRequest vs timeoutIntervalForResource?
https://github.com/Alamofire/Alamofire/issues/1266

> TimeoutIntervalForRequest
The max time interval to wait between server responses before cancelling the request. All session tasks use this value, but it is really designed for tasks running on a default or ephemeral session. Tasks running on a background session will automatically be retried.

> Unless you are using background sessions or download massive payloads, this is most likely the only property you need to worry about.

> TimeoutIntervalForResource
The max time interval allowed for downloading a request payload. The default value is 7 days. While this can be used for default and ephemeral sessions to specify something like no request should take more than 5 minutes to complete, it's really intended for upload and download tasks running on a background session. Background URL sessions will automatically retry failed tasks behind the scenes until the timeoutIntervalForResource is reached. You won't receive a failure until this interval is reached for background sessions.


## Tempus - 昨今明日
https://blogger.tempus.org/2013/11/nsurlconnection-nsurlsession.html

> timeoutIntervalForRequestは、データ間のタイムアウトを設定するプロパティです。このタイマは新しいデータが到着するとリセットされます。呼の確立までの間や、データが複数個へ分割されている場合など、各データ間のタイムアウト値が設定可能であり、通信が確立できないまま、または切れてしまったまま、長時間待ち状態になる事態を回避できます。

> timeoutIntervalForResourceは、従来のNSURLRequestで使われていたtimeoutIntervalに近い機能を持つもので、URLで指定されたデータの取得処理が完了するまでの時間を指定するものです。これは、伝送速度が非常に遅い環境など、通信完了まで非常に長い時間を要してしまう状況を回避するために利用できます。

> 大変に便利な仕様なのですが、しかし、iOS7.0.3で動作確認を行ったところ、timeoutIntervalForRequestは、データを受信時にタイマがリセットされる状況を作り出すことが出来ませんでした。またその為か、timeoutIntervalForRequestとtimeoutIntervalForResourceの両者を設定した場合、単純に、より短い値がtimeoutIntervalForResource用のタイムアウト値として使われていました。ドキュメントへ書いてある「データ」が、今回の利用想定と異なっているのかもしれません。

# 以上のドキュメントからの結論

### timeoutIntervalForRequest
データ転送ができない状態で待機する時間。**リクエスト、レスポンスどちらにも適用される**。
この設定値より長く、サーバーとの疎通が取れない場合や、レスポンスデータの転送が始まらない場合にタイムアウトする。
例えばこの値を10秒にすると、サーバーのレスポンス処理に10秒以上かかった場合もタイムアウトしてしまうので注意が必要。

レスポンスが複数のデータ転送に分かれる場合、それぞれのデータ転送が行われるたび、タイムアウトのタイマーはリセットされるがそのケースはあまりないものと思われる。
※Transfer-Encoding chunkedの場合とかかな？

### timeoutIntervalForResource
通信全体のタイムアウト時間。