기존 콜백/Combine을 async/await로 연결하기
withCheckedContinuation / withCheckedThrowingContinuation 으로 완료 처리기를 감싸고, Combine 게시자를 AsyncSequence 로 연결해 간단한 for await 반복문에서 사용합니다.
기존 콜백/Combine을 async/await로 연결하기은(는) CoddyKit의 무료 Swift Academy 강의입니다. 이것은 3개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Swift Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Swift Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
연결이 필요한 이유
목표: 컨티뉴에이션을 사용해 콜백을 감싸고, Combine 스트림을 AsyncSequence로 다루십시오.
- 컨티뉴에이션(오류를 던지지 않는 방식/오류를 던지는 방식)
- URLSession 연결 예시
- Combine에서
for await로 값 소비하기
오류를 던지지 않는 컨티뉴에이션
기존 API가 실패할 수 없을 때는 withCheckedContinuation을 사용하십시오. 정확히 한 번만 재개해야 합니다.
// 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"
}오류를 던지는 컨티뉴에이션
withCheckedThrowingContinuation을 사용해 기존 API의 오류를 throw로 전달하십시오. 재개 경로가 하나뿐인지 확인하십시오.
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 연결
완료 핸들러 API(예: URLSession)를 감싸 깔끔한 비동기 오류 처리 함수를 만드십시오. 정확히 한 번만 재개해야 한다는 점을 기억하십시오.
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을 AsyncSequence로 사용하기
많은 Combine 퍼블리셔는 .values를 제공하므로, 사용자 지정 연결 코드 없이 방출된 값을 for await로 순회할 수 있습니다.
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)퍼블리셔 → AsyncStream
.values를 사용할 수 없다면 AsyncStream으로 간단한 연결 코드를 만드십시오. 작업이 끝나면 구독을 cancel하는 것도 잊지 마십시오.
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
}오류를 던지는 컨티뉴에이션 사용
간단 확인: 실패할 수 있는 콜백을 비동기 코드로 연결하는 가장 좋은 방법은 무엇인가요?
요약
요약: 기존 콜백을 컨티뉴에이션(오류를 던지는 방식 또는 그렇지 않은 방식)으로 감싸고, Combine은 .values나 작은 AsyncStream 연결 코드로 소비하십시오. 재개는 한 번만 수행하고, 완료 시 구독을 cancel하십시오.
AI 튜터와 함께 Swift을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 122
- 레슨
- 409
자주 묻는 질문
“기존 콜백/Combine을 async/await로 연결하기” 강의는 무료인가요?
네 — “기존 콜백/Combine을 async/await로 연결하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Swift Academy 강의 전체를 잠금 해제할 수 있습니다. Swift Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
“기존 콜백/Combine을 async/await로 연결하기”에서 뭘 배우나요?
withCheckedContinuation / withCheckedThrowingContinuation 으로 완료 처리기를 감싸고, Combine 게시자를 AsyncSequence 로 연결해 간단한 for await 반복문에서 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 Swift Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Swift Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Swift Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 2번째 강의입니다.
“기존 콜백/Combine을 async/await로 연결하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Swift Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Swift Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 생산자/소비자, 파이프라인, 시간 초과
- 기존 콜백/Combine을 async/await로 연결하기
- 비동기 코드 테스트(XCTest)