0Pricing
Swift Academy · Lektion

Legacy-Callbacks/Combine mit async/await verbinden

Verpacken Sie Completion-Handler mit withCheckedContinuation / withCheckedThrowingContinuation und verbinden Sie Combine -Publisher für einfache for await -Schleifen mit AsyncSequence .

Legacy-Callbacks/Combine mit async/await verbinden ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 3. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 3 Lektionen.

Warum überbrücken?

Ziel: Verwenden Sie Continuations, um Callbacks zu kapseln und Combine-Streams als AsyncSequence zu behandeln.

  • Continuations (nicht fehlerwerfend / fehlerwerfend)
  • Beispiel für eine URLSession-Bridge
  • Combine → for await-Verarbeitung

Nicht fehlerwerfende Continuation

Verwenden Sie withCheckedContinuation, wenn die Legacy-API nicht fehlschlagen kann. Setzen Sie die Continuation genau einmal fort.

// Old-style API
func fetchName(completion: @escaping (String) -> Void) {
    // simulate async
    Task { try? await Task.sleep(nanoseconds: 80_000_000); completion("Ana") }
}

// Async wrapper using continuation (non-throwing)
func fetchName() async -> String {
    await withCheckedContinuation { (cont: CheckedContinuation<String, Never>) in
        fetchName { value in cont.resume(returning: value) }
    }
}

Task {
    let name = await fetchName()
    print("name:", name) // "Ana"
}

Fehlerwerfende Continuation

Verwenden Sie withCheckedThrowingContinuation, um Legacy-Fehler über throw weiterzugeben. Stellen Sie einen einzigen Resume-Pfad sicher.

enum NetError: Error { case offline; case badStatus }

func loadNumber(completion: @escaping (Result<Int, Error>) -> Void) {
    Task {
        try? await Task.sleep(nanoseconds: 80_000_000)
        completion(.failure(NetError.offline))
    }
}

func loadNumber() async throws -> Int {
    try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Int, Error>) in
        loadNumber { result in
            switch result {
            case .success(let v): cont.resume(returning: v)
            case .failure(let e): cont.resume(throwing: e)
            }
        }
    }
}

Task {
    do {
        let n = try await loadNumber()
        print(n)
    } catch {
        print("error:", error) // offline
    }
}

URLSession-Bridge

Kapseln Sie APIs mit Completion-Handlern (z. B. URLSession), um eine klare async throws-Funktion zu erhalten. Denken Sie daran, die Continuation genau einmal fortzusetzen.

import Foundation

func getText(from url: URL) async throws -> String {
    try await withCheckedThrowingContinuation { (cont: CheckedContinuation<String, Error>) in
        let task = URLSession.shared.dataTask(with: url) { data, resp, err in
            if let err = err { cont.resume(throwing: err); return }
            guard let data = data, let text = String(data: data, encoding: .utf8) else {
                cont.resume(throwing: URLError(.badServerResponse)); return
            }
            cont.resume(returning: text)
        }
        task.resume()
    }
}

// Demo (works in environments with network access)
let demoURL = URL(string: "https://example.com")!
Task {
    do { let body = try await getText(from: demoURL); print(body.prefix(15)) }
    catch { print("network error:", error) }
}

Combine als AsyncSequence

Viele Combine-Publisher stellen .values bereit. Dadurch können Sie mit for await über Emissionen iterieren, ohne eigene Bridges zu erstellen.

import Combine
import Foundation

let subject = PassthroughSubject<Int, Never>()

// Consume Combine as AsyncSequence:
Task {
    var produced: [Int] = []
    for await value in subject.values {          // Publisher.values -> AsyncSequence
        produced.append(value)
        if produced.count == 3 { break }         // stop after 3 values
    }
    print("collected:", produced)                // e.g., [1,2,3]
}

// Publish a few values
var cancellables = Set<AnyCancellable>()
Timer.publish(every: 0.05, on: .main, in: .common)
    .autoconnect()
    .prefix(3)
    .scan(0) { acc, _ in acc + 1 }
    .sink { subject.send($0) }
    .store(in: &cancellables)

Publisher → AsyncStream

Wenn .values nicht verfügbar ist, erstellen Sie mit AsyncStream eine kleine Bridge. Vergessen Sie nicht, die Subscription nach Abschluss zu kündigen.

import Combine

// Bridge ANY Publisher to AsyncSequence using AsyncStream (simple version)
extension Publisher {
    func asAsyncStream() -> AsyncStream<Output> {
        AsyncStream { continuation in
            let cancel = self.sink(
                receiveCompletion: { _ in continuation.finish() },
                receiveValue: { value in continuation.yield(value) }
            )
            continuation.onTermination = { _ in cancel.cancel() }
        }
    }
}

// Demo:
let pub = [10, 20, 30].publisher
Task {
    var sum = 0
    for await v in pub.asAsyncStream() { sum += v }
    print("sum:", sum) // 60
}

Throwing-Continuation verwenden

Kurzprüfung: Wie lässt sich ein fehlerbehafteter Callback am besten an async anbinden?

Zusammenfassung

Zusammenfassung: Kapseln Sie Legacy-Callbacks mit Continuations (fehlerwerfend oder nicht) und verarbeiten Sie Combine mit .values oder einer kleinen AsyncStream-Bridge. Setzen Sie Continuations immer nur einmal fort und kündigen Sie Subscriptions nach Abschluss.

Häufig gestellte Fragen

Ist die Lektion „Legacy-Callbacks/Combine mit async/await verbinden“ kostenlos?

Ja — der vollständige Text von „Legacy-Callbacks/Combine mit async/await verbinden“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 3 Lektionen.

Was lerne ich in „Legacy-Callbacks/Combine mit async/await verbinden“?

Verpacken Sie Completion-Handler mit withCheckedContinuation / withCheckedThrowingContinuation und verbinden Sie Combine -Publisher für einfache for await -Schleifen mit AsyncSequence . Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Swift Academy zu starten?

Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 3.

Wie lange dauert die Lektion „Legacy-Callbacks/Combine mit async/await verbinden“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?

Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Producer/Consumer, Pipelines und Timeouts
  2. Legacy-Callbacks/Combine mit async/await verbinden
  3. Asynchronen Code testen (XCTest)
← Zurück zu Swift Academy