0Pricing
Swift Academy · Урок

Логика повторных попыток и фоновый 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 — локальная установка не требуется.

Все уроки этого курса

  1. URLSession data(from:) с async/await
  2. Codable: кодирование и декодирование JSON
  3. Обработка ошибок и коды состояния HTTP
  4. Логика повторных попыток и фоновый URLSession
← Назад к Swift Academy