Как обработать ситуацию, когда сервер не отвечает и нужно показать сообщение пользователю
Что проверяют
Различаете ли вы виды сетевых сбоев и умеете ли превратить их в понятное состояние экрана. Показать UIAlertController может каждый, интересно, как вы отличите таймаут от отсутствия сети и от ответа 500. Следом спрашивают про повтор запроса и про то, что видит пользователь во время ожидания.
Как отвечать
Разложите ответ по слоям:
- таймауты: у
URLSessionConfigurationпо умолчаниюtimeoutIntervalForRequestравен 60 секундам. Для интерактивного экрана минута спиннера слишком долго, таймаут обычно уменьшают; - классификация: транспортные сбои приходят как
URLError:.timedOut,.notConnectedToInternet,.cannotConnectToHost,.networkConnectionLost. Ответ 5xx дляURLSessionошибкой не считается,errorбудетnil, статус проверяйте вHTTPURLResponse.statusCodeсами; - доменная ошибка: сетевой слой переводит всё это в свой
enum NetworkError, экран не разбираетURLErrorнапрямую; - состояние экрана: запрос через
try await session.data(for: request), ViewModel под@MainActorпубликуетloading,contentилиfailed. Для ошибки загрузки лучше встроенная заглушка с кнопкой «Повторить», чем алерт. Есть кеш: показывайте его с плашкой «нет связи»; - повтор: автоматически и с экспоненциальной задержкой ретраят только идемпотентные запросы. Для ожидания сети есть
waitsForConnectivityв конфигурации сессии, состояние подключения отслеживаетNWPathMonitor.
Текст ошибки пишите сами и локализуйте: localizedDescription системной ошибки пользователю ничего не объясняет.
Где спотыкаются
Проверяют только error и считают любой ответ успехом. Сервер вернул 503 с HTML-страницей, декодер падает, и пользователь видит «данные повреждены» вместо «сервис недоступен».
Показывают ошибку на отменённый запрос. Пользователь ушёл с экрана, задача получила URLError.cancelled, и выскакивает алерт, которого никто не ждал.
Складывают алерты стопкой: три параллельных запроса падают разом и пытаются показать три окна. Контроллер, который уже что-то показывает, второй present не выполнит, и остальные сообщения теряются с предупреждением в логе.