반응형
Combine의 핵심 구성 요소는 Publisher와 Subscriber로, Publisher는 데이터를 발행하고 Subscriber는 이를 구독하여 처리합니다.
Publisher
Combine의 핵심 프로토콜로, 데이터 스트림을 생성하고 구독자에게 전달하는 역할
Publisher는 타입을 가집니다:
- Output: 발행하는 데이터의 타입
- Failure: 오류의 타입
Just
- Just는 단일 값을 발행하고 완료하는 가장 간단한 Publisher입니다. 주로 고정된 값을 전달할 때 사용합니다.
import Combine
let justPublisher = Just("Hello, Just!")
let subscriber = justPublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 출력:
// 값: Hello, Just!
// 완료: finished
- 간단하고 직관적
- 테스트나 디버깅 시 유용
- 고정된 데이터를 전달할 때 효율적
Sequence
- Sequence Publisher는 Swift의 Sequence 타입을 Publisher로 변환합니다.
배열, 범위 등 시퀀스 데이터를 발행할 때 사용됩니다.
import Combine
let numbers = [1, 2, 3, 4, 5]
let sequencePublisher = numbers.publisher
let subscriber = sequencePublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 출력:
// 값: 1
// 값: 2
// 값: 3
// 값: 4
// 값: 5
// 완료: finished
- 시퀀스 데이터를 쉽게 발행
- 다양한 시퀀스 타입과 호환 가능
- 데이터 스트림을 자연스럽게 처리
Future
- Future는 비동기 작업의 결과를 한 번만 발행하는 Publisher입니다.
주로 네트워크 요청이나 비동기 계산 결과를 전달할 때 사용됩니다.
import Combine
func fetchData() -> Future<String, Error> {
return Future { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
promise(.success("데이터 로드 완료"))
}
}
}
let futurePublisher = fetchData()
let subscriber = futurePublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 2초 후 출력:
// 값: 데이터 로드 완료
// 완료: finished
- 비동기 작업의 결과를 쉽게 전달
- 오류 처리 가능
- 단일 값 발행에 적합
Fail
- Fail은 즉시 오류를 발행하고 완료하는 Publisher입니다.
오류를 테스트하거나 오류 시나리오를 시뮬레이션할 때 유용합니다.
import Combine
enum MyError: Error {
case somethingWentWrong
}
let failPublisher = Fail<String, MyError>(error: .somethingWentWrong)
let subscriber = failPublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 출력:
// 완료: failure(MyError.somethingWentWrong)
Empty
- Empty는 아무 값도 발행하지 않고 즉시 완료하는 Publisher입니다.
특정 상황에서 아무 작업도 하지 않도록 할 때 사용됩니다.
import Combine
let emptyPublisher = Empty<String, Never>()
let subscriber = emptyPublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 출력:
// 완료: finished
- 아무 데이터도 필요하지 않은 상황에서 유용
- 다른 Publisher와 결합할 때 기본 값으로 사용 가능
Deferred
- Deferred는 실제로 구독할 때 Publisher를 생성하는 Publisher입니다.
Publisher 생성 시점을 지연시키고 싶을 때 유용합니다.
import Combine
func createDeferredPublisher() -> AnyPublisher<String, Never> {
return Deferred {
Future { promise in
promise(.success("Deferred 값"))
}
}
.eraseToAnyPublisher()
}
let deferredPublisher = createDeferredPublisher()
let subscriber = deferredPublisher.sink(
receiveCompletion: { completion in
print("완료: \(completion)")
},
receiveValue: { value in
print("값: \(value)")
}
)
// 출력:
// 값: Deferred 값
// 완료: finished
- Publisher 생성 시점 제어
- 지연 초기화
- 동적인 Publisher 생성 가능
반응형