0Pricing
Swift Academy · Lección

Lógica de reintentos y URLSession en segundo plano

Implemente un retroceso exponencial y continúe las descargas en segundo plano.

Lógica de reintentos y URLSession en segundo plano es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

¿Por qué reintentar?

Los fallos transitorios (tiempos de espera agotados y 503 Service Unavailable) se pueden recuperar. La lógica de reintento mejora la resiliencia sin intervención del usuario.

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")
}

Retroceso exponencial

Espere cada vez más tiempo entre reintentos para evitar saturar un servidor con problemas: 1 s, 2 s y 4 s.

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 }
  }
}

Jitter para evitar la estampida

Añada un jitter aleatorio a los retrasos del retroceso para que los clientes que reintentan no accedan al servidor todos al mismo tiempo.

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))

Errores reintentables y no reintentables

Reintente únicamente los errores transitorios. Los errores del cliente (401 y 400) no deben reintentarse.

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 en segundo plano

Una sesión en segundo plano continúa las descargas incluso cuando la aplicación está suspendida o terminada.

let config = URLSessionConfiguration.background(withIdentifier: "com.myapp.background")
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

URLSessionDelegate para segundo plano

Implemente URLSessionDelegate para recibir devoluciones de llamada de finalización cuando la aplicación se vuelva a iniciar después de que termine una tarea en segundo plano.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
  let dest = documentsURL.appendingPathComponent("download.pdf")
  try? FileManager.default.moveItem(at: location, to: dest)
}

Controlador de actualización de la aplicación en segundo plano

En AppDelegate, guarde el controlador de finalización en segundo plano y llámelo cuando terminen todas las tareas.

func application(_ app: UIApplication, handleEventsForBackgroundURLSession id: String, completionHandler: @escaping () -> Void) {
  backgroundCompletionHandler = completionHandler
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
  DispatchQueue.main.async { self.backgroundCompletionHandler?() }
}

Tarea de descarga con una sesión en segundo plano

Use downloadTask(with:) en una sesión en segundo plano para realizar descargas resilientes de archivos grandes.

let task = session.downloadTask(with: URL(string: "https://cdn.example.com/large.zip")!)
task.resume()

Tarea de carga en segundo plano

Las sesiones en segundo plano también admiten tareas de carga que continúan cuando la aplicación no está en ejecución.

var request = URLRequest(url: uploadURL)
request.httpMethod = "POST"
let task = session.uploadTask(with: request, fromFile: localFileURL)
task.resume()

Supervisión del progreso

Observe URLSessionTaskDelegate para realizar un seguimiento del progreso de las cargas y descargas y actualizar la interfaz.

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 }
}

Combinación de reintentos con el segundo plano

Use reintentos en primer plano para las llamadas a API y sesiones en segundo plano para las descargas y cargas de larga duración.

// API calls: async/await + exponential backoff retry
// Large downloads: URLSessionConfiguration.background + delegate

Comprobación rápida

¿Qué técnica evita que los clientes que reintentan accedan al servidor todos en el mismo momento?

Resumen de la lección

Implemente reintentos con retroceso exponencial y jitter para los errores transitorios. Reintente únicamente los errores 5xx y los tiempos de espera agotados. Use URLSessionConfiguration.background con un delegado para las descargas y cargas que deben sobrevivir a la suspensión de la aplicación.

Preguntas frecuentes

¿La lección «Lógica de reintentos y URLSession en segundo plano» es gratis?

Sí — el texto completo de «Lógica de reintentos y URLSession en segundo plano» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Lógica de reintentos y URLSession en segundo plano»?

Implemente un retroceso exponencial y continúe las descargas en segundo plano. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Lógica de reintentos y URLSession en segundo plano»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. URLSession data(from:) con async/await
  2. Codable: codificación y decodificación de JSON
  3. Gestión de errores y códigos de estado HTTP
  4. Lógica de reintentos y URLSession en segundo plano
← Volver a Swift Academy