> Как реализовать удаление нескольких элементов при ограничении бэкенда на один запрос на удаление (iOS, Swift)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Совкомбанк

Стек: iOS, Swift

> Пример ответа

Когда бэкенд поддерживает только удаление одного элемента за запрос, а нужно удалить несколько, оптимальное решение - выполнить серию параллельных или последовательных запросов с контролем ошибок и отменой.

Вариант 1: Последовательное удаление с обработкой ошибок
Используем async/await для последовательного выполнения, чтобы не перегружать сервер и корректно обрабатывать частичные сбои:

SWIFT
func deleteItems(_ ids: [Int]) async throws {
for id in ids {
try await api.deleteItem(id: id)
}
}

Если нужно уведомить пользователя о частичном успехе, можно возвращать массив ошибок или использовать Result.

Вариант 2: Параллельное удаление с ограничением (Concurrency)
Для ускорения можно запустить несколько запросов одновременно, но ограничить количество параллельных операций (например, 3-5), чтобы не заблокировать сеть:

SWIFT
func deleteItemsConcurrently(_ ids: [Int], maxConcurrent: Int = 3) async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
for id in ids {
group.addTask { try await api.deleteItem(id: id) }
if group.taskCount >= maxConcurrent {
try await group.next() // ждем завершения одной задачи
}
}
}
}

Вариант 3: Пакетное удаление с подтверждением
Если бэкенд может принять список ID в одном запросе, но ограничен по количеству - разбиваем на пачки (например, по 10):

SWIFT
func deleteBatch(_ ids: [Int], batchSize: Int = 10) async throws {
for batch in ids.chunked(into: batchSize) {
try await api.deleteBatch(ids: batch)
}
}

(метод chunked можно реализовать через Array extension).

Рекомендация:

  • Для UI: показывать прогресс (например, ProgressView с индикацией количества удаленных элементов).

  • Для отмены: использовать Task с isCancelled проверкой внутри цикла.

  • Для ошибок: реализовать повторную попытку (retry) для отдельных элементов, если сервер временно недоступен.

Пример с отменой и обработкой ошибок:

SWIFT
func deleteItemsWithCancel(_ ids: [Int]) async throws {
var failedIds: [Int] = []
for id in ids {
guard !Task.isCancelled else { throw CancellationError() }
do {
try await api.deleteItem(id: id)
} catch {
failedIds.append(id)
}
}
if !failedIds.isEmpty {
throw DeletionError.partialFailure(failedIds: failedIds)
}
}

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью