컴바인을 사용하는 이유
텍스트 필드에 입력된 값을 다음 vc에 전달하는 코드가 있다고 가정할때,
1. Delegate 패턴
Delegate 패턴은 객체 간의 커뮤니케이션을 위해 인터페이스를 정의하고, 하나의 객체가 다른 객체를 대신해서 작업을 수행하도록 합니다.
WelcomeViewController.swift
protocol WelcomeViewControllerDelegate: AnyObject {
func didReceiveNickname(_ nickname: String)
}
class WelcomeViewController: UIViewController {
weak var delegate: WelcomeViewControllerDelegate?
func updateUIWithNickname() {
delegate?.didReceiveNickname("Nickname")
}
}
extension SomeOtherViewController: WelcomeViewControllerDelegate {
func didReceiveNickname(_ nickname: String) {
// UI 업데이트
print("Received nickname: \\(nickname)")
}
}
2. 콜백 함수
클로저로 콜백을 준 경우
WelcomeViewController.swift
class WelcomeViewController: UIViewController {
var onReceiveNickname: ((String) -> Void)?
func fetchNickname() {
//닉네임 가져오기
onReceiveNickname?("Nickname")
}
}
// 다른 VC
let welcomeVC = WelcomeViewController()
welcomeVC.onReceiveNickname = { nickname in
// UI 업데이트
print("Received nickname: \\(nickname)")
}
3. Completion 클로저
Completion 클로저는 비동기 작업이 끝났을 때 실행되는 클로저로, 작업의 결과를 클로저를 통해 반환합니다. 이 방식은 비동기 작업이 완료된 후 필요한 동작을 수행할 때 주로 사용됩니다.
WelcomeViewController.swift
class WelcomeViewController: UIViewController {
func fetchNickname(completion: @escaping (String) -> Void) {
// 닉네임을 가져오는 작업
completion("Nickname")
}
}
// 사용 예
let welcomeVC = WelcomeViewController()
welcomeVC.fetchNickname { nickname in
// UI 업데이트
print("Received nickname: \\(nickname)")
}
4. Combine
WelcomeViewController.swift
import Combine
class WelcomeViewController: UIViewController {
var nicknamePublisher = PassthroughSubject<String, Never>()
func publishNickname() {
nicknamePublisher.send("Nickname")
}
}
// 다른 뷰 컨트롤러에서 구독
let welcomeVC = WelcomeViewController()
var cancellables = Set<AnyCancellable>()
welcomeVC.nicknamePublisher
.sink(receiveValue: { nickname in
// UI 업데이트
print("Received nickname: \\(nickname)")
})
.store(in: &cancellables)
결론
- Delegate 패턴: 유연성이 떨어질 수 있다.
- 콜백 함수 및 Completion 클로저: 쉽지만 콜백지옥에 빠지면 곤란하다
- Combine: 모던하고 쌈@뽕하다.
Combine Overview
Event Stream (Event pipeline)
Publisher가 정보를 만들어서 내뱉으면 Subscriber가 최종적으로 정보를 받는 형태입니다.
이때 Operator가 작업해서 값을 변경할수도 안할수도 있는 그런 역할을 합니다.
3가지 주요 컴포넌트
1대1로 비교하기에는 무리가 있겠지만 대충 이런느낌으로 저는 이해했어요
- Publisher
유튜버 - 컨텐츠 생산자 - Subscriber
구독자 - 사용자 - Operator
편집자 - 조정자
— — —
- Subscription
- 구독티켓? 구독중인 버튼? - 구독자만 이용할수 있는 티켓
Publisher
Declares that a type can transmit a sequence of values over time.
타입이 시간 경과에 따라 일련의 값을 전송할 수 있음을 선언합니다.
- 데이터를 전송(배출)할수 있다.
- output: 발행하는 값의 종류, Failure : 오류값
- Subscriber 가 요청한것 만큼 데이터를 제공
- Failure 타입을 Never로 지정하면 오류를 반환하지 않는것 (Just가 그 예시중 하나)
- 빌트인 Publisher인 Just, Future 가 있음
- Just 는 값을 다룬다 → 고정된 값을 비동기처리할때 사용
- Future 는 함수값을 다룬다 → 시간좀 걸리는 비동기 작업처리할때 사용
- 자동으로 제공해주는것들 (addOberser 등 메서드를 붙이지 않고 바로 publish를 붙혀서 사용할수 있는것)
- NotificationCenter
- Timer
- URLSession.dataTask
Subscriber
퍼블리셔로부터 입력을 받을 수 있는 유형을 선언하는 프로토콜입니다.
정의된 값을 보면
- Publisher 에게 데이터 요청하는 프로토콜
- Input, Failure 타입이 정의가 필요합니다
- input은 구독자가 받는 값의 종류를 뜻합니다.
- 오류를 받지 않는 경우 Never를 사용함
- Publisher 구독후( receive(subscription:) ), 갯수를 요청함
- 파이프라인을 취소할 수 있음
- 빌트인 Subscriber인 assign 과 sink 가 있음
- assign 는 Publisher가 제공한 데이터를 특정 객체의 키패스에 할당
- sink 는 Publisher가 제공한 데이터를 받을수 있는 클로져를 제공함
두개의 주고받는 관계
- Subscriber가 Publisher에 붙는다 ( 값을 요청한다 )
- 값이 붙엇으면(구독이 성공하면) subscription 라는걸 준다
- subscription가 몇개의 데이터가 필요하다고 요청을 한다
- 이후 Publisher가 필요한 만큼 값을 준다
Publisher는 값을 계속 찍어내는데 Subscriber는 그게 필요하니 가서 달라고 요청하는것
Subscription
A protocol representing the connection of a subscriber to a publisher.
subscriber와 publisher의 연결을 나타내는 프로토콜입니다.
- Subscriber 가 Publisher가 연결됨을 나타내는 녀석
- 쉽게 생각하면, Publisher 가 발행한 구독 티켓
- 이 구독 티켓만 있으면, 데이터를 받을수 있음
- 이 구독 티켓이 사라지면 구독 관계도 사라짐
- Cancellable protocol을 따르고 있음
- 따라서, Subscription 을 통해 연결을 Cancel 할수 있다
Operator
- Publisher 에게 받은 값을 가공해서 Subscriber 에게 제공
- Input, Output, Failure type 을 받는데 타입이 다를수 있음
- 빌트인 오퍼레이터가 개많이 있음
참고
https://developer.apple.com/videos/play/wwdc2019/722/
https://developer.apple.com/videos/play/wwdc2019/721/
https://developer.apple.com/documentation/combine/using-combine-for-your-app-s-asynchronous-code
https://developer.apple.com/documentation/combine/replacing-foundation-timers-with-timer-publishers
https://developer.apple.com/documentation/combine/processing-published-elements-with-subscribers
https://sujinnaljin.medium.com/combine-sink-assign-3dc04b7b326f
https://developer.apple.com/documentation/combine/receiving-and-handling-events-with-combine
https://fastcampus.co.kr/dev_online_iosbible
https://developer.apple.com/videos/play/wwdc2019/722/
https://leetaek.tistory.com/69
https://todayssky.tistory.com/17
'IOS - Swift > Combine' 카테고리의 다른 글
[iOS/Combine] Combine - Error Handling (0) | 2024.12.12 |
---|---|
[iOS/Combine] Transforming Operators (4) | 2024.12.05 |
subscription의 이해 (0) | 2024.11.25 |
Publisher - Just, Empty, Failure (1) | 2024.10.03 |
Combine - Publisher 기초 (2) | 2024.10.01 |