Conectando callbacks legados/Combine a async/await
Envolva manipuladores de conclusão usando withCheckedContinuation / withCheckedThrowingContinuation e conecte publishers de Combine a AsyncSequence para loops simples for await .
Conectando callbacks legados/Combine a async/await é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 3 aulas no total.
Por que fazer a ponte?
Objetivo: Use continuações para encapsular retornos de chamada e tratar fluxos do Combine como AsyncSequence.
- Continuações (sem lançamento de erros ou com lançamento de erros)
- Exemplo de integração com URLSession
- Consumo de Combine →
for await
Continuação sem lançamento de erros
Use withCheckedContinuation quando a API antiga não puder falhar. Retome exatamente uma vez.
// 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"
}Continuação com lançamento de erros
Use withCheckedThrowingContinuation para expor erros da API antiga por meio de throw. Garanta um único caminho de retomada.
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
}
}Integração com URLSession
Encapsule APIs com manipuladores de conclusão, como URLSession, para obter uma função limpa assíncrona que lança erros. Lembre-se de retomar exatamente uma vez.
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 como AsyncSequence
Muitos publicadores do Combine expõem .values, permitindo usar for await sobre as emissões sem criar pontes personalizadas.
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)Publicador → AsyncStream
Se .values não estiver disponível, crie uma pequena ponte usando AsyncStream. Não se esqueça de cancelar a assinatura ao terminar.
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
}Use uma continuação com lançamento de erros
Verificação rápida: Qual é a melhor maneira de conectar um retorno de chamada que pode falhar ao código assíncrono?
Recapitulação
Recapitulação: Encapsule retornos de chamada antigos com continuações (com ou sem lançamento de erros) e consuma Combine usando .values ou uma pequena ponte com AsyncStream. Mantenha as retomadas únicas e cancele as assinaturas ao finalizar.
Aprenda Swift com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 122
- Aulas
- 409
Perguntas Frequentes
A aula “Conectando callbacks legados/Combine a async/await” é grátis?
Sim — o texto completo de “Conectando callbacks legados/Combine a async/await” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 3 aulas no total.
O que vou aprender em “Conectando callbacks legados/Combine a async/await”?
Envolva manipuladores de conclusão usando withCheckedContinuation / withCheckedThrowingContinuation e conecte publishers de Combine a AsyncSequence para loops simples for await . Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 3.
Quanto tempo leva a aula “Conectando callbacks legados/Combine a async/await”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Produtor/consumidor, pipelines e timeouts
- Conectando callbacks legados/Combine a async/await
- Testando código assíncrono (XCTest)