Как реализовать тайм-аут ожидания ответа от сервера
Что проверяют
Знаете ли вы, что два тайм-аута URLSession означают разные вещи, и умеете ли отличить тайм-аут от прочих сетевых ошибок. Следом часто спрашивают, как ограничить общее время операции и что делать с запросом после тайм-аута.
Как отвечать
Разведите настройки:
timeoutIntervalForRequestуURLSessionConfigurationиtimeoutIntervalуURLRequest, по умолчанию 60 секунд. Это тайм-аут простоя: сколько ждать следующей порции данных. Таймер сбрасывается при каждом полученном пакете, поэтому медленная загрузка может длиться гораздо дольше минуты;timeoutIntervalForResource: общий лимит на весь ресурс, по умолчанию 7 дней. Его уменьшают, если нужен жёсткий потолок;waitsForConnectivity: приtrueзадача ждёт появления сети вместо мгновенной ошибки, и тогда решает ресурсный тайм-аут.
Обработка: с async/await пишете try await session.data(for: request) и в catch проверяете URLError с кодом .timedOut (это NSURLErrorTimedOut, код -1001). Отдельно разберите .notConnectedToInternet и .cancelled: для пользователя это разные сообщения.
Если нужен жёсткий дедлайн на всю операцию, включая разбор ответа, используют группу задач: одна задача делает запрос, другая ждёт через Task.sleep и бросает ошибку, первый результат забирают, остальное отменяют через cancelAll(). Async-методы URLSession уважают отмену Task. В Combine есть оператор timeout, в Alamofire тайм-аут задаётся через конфигурацию сессии или requestModifier.
Для экрана продумайте поведение: индикатор загрузки, понятная ошибка с кнопкой повтора, отмена задачи при закрытии экрана, повтор с экспоненциальной задержкой для идемпотентных запросов.
Где спотыкаются
Считают timeoutIntervalForRequest общим временем запроса. Ответ, который приходит по байту раз в полминуты, такой тайм-аут не прервёт никогда.
Автоматически повторяют POST после тайм-аута. Сервер мог уже обработать запрос, и пользователь получит двойной платёж, поэтому без ключа идемпотентности такие запросы не повторяют.
Ставят маленький timeoutIntervalForResource на всю сессию, а потом удивляются обрыву загрузки больших файлов или видео.