Как сделать несколько последовательных запросов через URLSession
Что проверяют
Умеете ли вы строить цепочку зависимых запросов без «пирамиды» замыканий и понимаете ли разницу между последовательным и параллельным выполнением. Следом спрашивают, как отменить цепочку при уходе с экрана и как обработать ошибку на середине.
Как отвечать
Сейчас основной способ это async/await, доступный для URLSession с iOS 15. Последовательность получается сама собой: let (data, response) = try await session.data(from: firstURL), разбор ответа, затем второй try await с параметром из первого. Ошибка на любом шаге прерывает цепочку и ловится одним do/catch.
Что стоит добавить к каркасу:
- статус ответа:
data(from:)не бросает ошибку на 404 или 500. ПриведитеresponseкHTTPURLResponseи проверьтеstatusCode, иначе в декодер уйдёт страница с ошибкой; - сборка URL: параметры из первого ответа подставляйте через
URLComponentsиURLQueryItem, они экранируют значения. Склейка строки и force unwrap падают на первом пробеле; - отмена: запросы внутри
Taskотменяются вместе с задачей, и цепочка завершается ошибкой отмены. Во SwiftUI модификатор.taskотменяет задачу, когда экран исчезает; - поток: результат для интерфейса отдавайте на
@MainActor, а не из фонового колбэка; - много однотипных запросов подряд: обычный цикл
for id in ids { try await load(id) }выполнит их строго по очереди.
Для iOS ниже 15 или кода на замыканиях покажите вариант с вложенными completionHandler, вынесенными в отдельные функции, либо обёртку через withCheckedThrowingContinuation. DispatchGroup здесь не подходит: он нужен, чтобы дождаться нескольких параллельных запросов, а не выстроить их в очередь.
Где спотыкаются
Путают последовательное с параллельным: предлагают async let или withThrowingTaskGroup, когда второй запрос зависит от результата первого.
Пишут тесты с assert внутри колбэка. Тест завершается раньше, чем приходит ответ, и зеленеет без единой проверки. Нужны async тест-методы или XCTestExpectation, а сеть подменяют через URLProtocol.
Забывают [weak self] в цепочке замыканий или не отменяют задачу, и экран держится в памяти, пока не закончатся все запросы.