Swift Academy · Lekcja

Logika ponawiania i działanie URLSession w tle

Implementowanie wykładniczego zwiększania opóźnienia i kontynuowanie pobierania w tle.

Lekcja 4 z 413 kroki

Logika ponawiania i działanie URLSession w tle to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Po co ponawiać próby?

Przejściowe błędy, takie jak przekroczenie limitu czasu czy 503 Service Unavailable, można naprawić. Logika ponawiania prób zwiększa odporność aplikacji bez konieczności angażowania użytkownika.

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

Wykładnicze zwiększanie opóźnienia

Wydłużaj stopniowo czas oczekiwania między kolejnymi próbami, aby nie przeciążać przeciążonego serwera: 1 s, 2 s, 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 zapobiegający efektowi stada

Dodaj losowe odchylenie do opóźnień, aby klienci ponawiający próby nie wysyłali żądań do serwera dokładnie w tym samym czasie.

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

Błędy podlegające ponawianiu i pozostałe błędy

Ponawiaj próby tylko w przypadku błędów przejściowych. Błędów klienta, takich jak 401 czy 400, nie należy ponawiać.

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
}

Sesja URLSession działająca w tle

Sesja działająca w tle kontynuuje pobieranie, nawet gdy aplikacja jest zawieszona lub zakończona.

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

URLSessionDelegate dla sesji działających w tle

Zaimplementuj URLSessionDelegate, aby otrzymywać wywołania zwrotne o zakończeniu po ponownym uruchomieniu aplikacji, gdy zadanie działające w tle dobiegnie końca.

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

Obsługa odświeżania aplikacji w tle

W AppDelegate zapisz procedurę obsługi zakończenia zadania w tle i wywołaj ją po zakończeniu wszystkich zadań.

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

Zadanie pobierania z sesją działającą w tle

Użyj downloadTask(with:) w sesji działającej w tle, aby niezawodnie pobierać duże pliki.

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

Zadanie wysyłania danych w tle

Sesje działające w tle obsługują również zadania wysyłania danych, które są kontynuowane, gdy aplikacja nie jest uruchomiona.

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

Monitorowanie postępu

Obserwuj URLSessionTaskDelegate, aby śledzić postęp wysyłania i pobierania danych oraz aktualizować interfejs.

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

Łączenie ponawiania prób z działaniem w tle

Używaj ponawiania prób na pierwszym planie w przypadku wywołań API, a sesji działających w tle w przypadku długotrwałego pobierania i wysyłania danych.

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

Szybkie sprawdzenie

Jaka technika zapobiega wysyłaniu żądań przez wszystkich klientów ponawiających próby dokładnie w tym samym momencie?

Podsumowanie lekcji

Zaimplementuj ponawianie prób z wykładniczym zwiększaniem opóźnienia i jitterem w przypadku błędów przejściowych. Ponawiaj próby tylko dla błędów 5xx i przekroczeń limitu czasu. Użyj URLSessionConfiguration.background wraz z delegatem w przypadku pobierania i wysyłania danych, które muszą przetrwać zawieszenie aplikacji.

Bezpłatny start

Ucz się Swift dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
122
Lekcje
409

Często zadawane pytania

Czy lekcja „Logika ponawiania i działanie URLSession w tle” jest bezpłatna?

Tak — pełny tekst „Logika ponawiania i działanie URLSession w tle” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Logika ponawiania i działanie URLSession w tle”?

Implementowanie wykładniczego zwiększania opóźnienia i kontynuowanie pobierania w tle. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Logika ponawiania i działanie URLSession w tle”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. URLSession data(from:) z async/await
  2. Codable: kodowanie i dekodowanie JSON
  3. Obsługa błędów i kody statusu HTTP
  4. Logika ponawiania i działanie URLSession w tle
← Powrót do Swift Academy