0Pricing
Swift Academy · Lesson

Retry Logic and Background URLSession

Implementing exponential backoff and continuing downloads in the background.

Why Retry?

Transient failures (timeouts, 503 Service Unavailable) are recoverable. Retry logic improves resilience without user intervention.

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

Exponential Backoff

Wait increasingly longer between retries to avoid overwhelming a struggling server: 1s, 2s, 4s.

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

All lessons in this course

  1. URLSession data(from:) with async/await
  2. Codable: Encoding and Decoding JSON
  3. Error Handling and HTTP Status Codes
  4. Retry Logic and Background URLSession
← Back to Swift Academy