Логика повторных попыток и фоновый URLSession
Реализуйте экспоненциальную задержку и продолжайте загрузки в фоновом режиме.
«Логика повторных попыток и фоновый URLSession» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Зачем нужны повторные попытки
Временные сбои (истечение времени ожидания, ошибка 503 «Сервис недоступен») можно устранить. Логика повторных попыток повышает устойчивость без участия пользователя.
func fetch(retries: Int = 3) async throws -> Data {
for attempt in 0..<retries {
do {
return try await URLSession.shared.data(from: url).0
} catch {
if attempt == retries - 1 { throw error }
}
}
fatalError("unreachable")
}Экспоненциальная задержка между попытками
Увеличивайте интервалы между повторными попытками, чтобы не перегружать испытывающий проблемы сервер: 1 с, 2 с, 4 с.
for attempt in 0..<maxRetries {
do { return try await fetch() } catch {
if attempt < maxRetries - 1 {
try await Task.sleep(nanoseconds: UInt64(pow(2.0, Double(attempt))) * 1_000_000_000)
} else { throw error }
}
}Случайное отклонение для предотвращения лавины запросов
Добавляйте случайное отклонение к задержкам между попытками, чтобы повторяющие запрос клиенты не обращались к серверу одновременно.
let baseDelay = pow(2.0, Double(attempt))
let jitter = Double.random(in: 0..<1)
let delay = (baseDelay + jitter) * 1_000_000_000
try await Task.sleep(nanoseconds: UInt64(delay))Повторяемые и неповторяемые ошибки
Повторяйте только временные ошибки. Ошибки клиента (401, 400) не следует повторять.
func isRetryable(_ error: Error) -> Bool {
if let urlErr = error as? URLError {
return urlErr.code == .timedOut || urlErr.code == .networkConnectionLost
}
if let netErr = error as? NetworkError, case .httpError(let code) = netErr {
return code >= 500
}
return false
}Фоновый URLSession
Фоновая сессия продолжает загрузки, даже когда приложение приостановлено или завершено.
let config = URLSessionConfiguration.background(withIdentifier: "com.myapp.background")
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)URLSessionDelegate для фоновых задач
Реализуйте URLSessionDelegate, чтобы получать обратные вызовы о завершении, когда приложение перезапускается после завершения фоновой задачи.
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
let dest = documentsURL.appendingPathComponent("download.pdf")
try? FileManager.default.moveItem(at: location, to: dest)
}Обработчик фонового обновления приложения
В AppDelegate сохраните обработчик завершения фоновой задачи и вызовите его после завершения всех задач.
func application(_ app: UIApplication, handleEventsForBackgroundURLSession id: String, completionHandler: @escaping () -> Void) {
backgroundCompletionHandler = completionHandler
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async { self.backgroundCompletionHandler?() }
}Задача загрузки в фоновой сессии
Используйте downloadTask(with:) в фоновой сессии для надёжной загрузки больших файлов.
let task = session.downloadTask(with: URL(string: "https://cdn.example.com/large.zip")!)
task.resume()Задача отправки данных в фоне
Фоновые сессии также поддерживают задачи отправки данных, которые продолжаются, когда приложение не запущено.
var request = URLRequest(url: uploadURL)
request.httpMethod = "POST"
let task = session.uploadTask(with: request, fromFile: localFileURL)
task.resume()Отслеживание хода выполнения
Наблюдайте за URLSessionTaskDelegate, чтобы отслеживать ход загрузки и отправки данных для обновления интерфейса.
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
let progress = Double(totalBytesSent) / Double(totalBytesExpectedToSend)
DispatchQueue.main.async { self.uploadProgress = progress }
}Сочетание повторных попыток с фоновым режимом
Используйте повторные попытки в основном потоке для вызовов API, а фоновые сессии — для длительных загрузок и отправок данных.
// API calls: async/await + exponential backoff retry
// Large downloads: URLSessionConfiguration.background + delegateБыстрая проверка
Какая техника не позволяет клиентам, выполняющим повторные попытки, обращаться к серверу одновременно?
Итоги урока
Реализуйте повторные попытки с экспоненциальными задержками и случайным отклонением для временных ошибок. Повторяйте только ошибки 5xx и ошибки истечения времени ожидания. Используйте URLSessionConfiguration.background с делегатом для загрузок и отправок данных, которые должны переживать приостановку приложения.
Часто задаваемые вопросы
Урок «Логика повторных попыток и фоновый URLSession» бесплатный?
Да — полный текст урока «Логика повторных попыток и фоновый URLSession» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Логика повторных попыток и фоновый URLSession»?
Реализуйте экспоненциальную задержку и продолжайте загрузки в фоновом режиме. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Логика повторных попыток и фоновый URLSession»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- URLSession data(from:) с async/await
- Codable: кодирование и декодирование JSON
- Обработка ошибок и коды состояния HTTP
- Логика повторных попыток и фоновый URLSession