[Combine] 컴바인으로 이벤트 전달받고 다루기

J_sung_0o0
4 min readSep 29, 2020

비동기 소스로부터 이벤트를 전달받고 커스텀하기

Subscriber 에 퍼블리셔 연결하기

let pub = NotificationCenter.default
.publisher(for: NSControl.textDidChangeNotification, object: textField)

publisher(for:object:) : 어디서, 어떤 알림을 받고 싶은지 정하여 퍼블리셔 생성

내장형 Subscriber

Combine 은 2가지 built-in Subscriber 를 제공하고 있음. 자동으로 output 과 failure 를 매칭시켜줌.

sink(receiveCompletion:receiveValue:)

  • receiveCompletion: 퍼블리셔가 정상 종료 했는지 에러로 실패했는지 가리키는 enum 인 Subscribers.Completion 이 실행될 때 호출
  • receiveValue: 퍼블리셔로부터 element를 받을 때 실행
pub.sink(receiveCompletion: { ... },
receiveValue: { ... }

assign(to:on:)

전달받은 모든 element를 주어진 객체의 프로퍼티로 전부 할당. 이때 key path를 사용하여 프로퍼티에 접근

ex) .assign(to: \MyViewModel.filterString, on: myViewModel)

Main thread 로 콜백 전달하기

결과가 UI 업데이트에 사용된다면 콜백들을 main thread 로 전달해주기 위해 receive(on:options:) 메소드를 호출해주면 됩니다.

let sub = NotificationCenter.default
.publisher(for: NSControl.textDidChangeNotification, object: filterField)
.map( { ($0.object as! NSTextField).stringValue } )
.filter( { ... } )
.debounce(for: .milliseconds(500), scheduler: RunLoop.main)
.receive(on: RunLoop.main)
.assign(to:\MyViewModel.filterString, on: myViewModel)

퍼블리싱 취소하기

더이상 퍼블리셔를 구독할 필요가 없다면 구독을 취소할 수 있습니다. 내장형 Subscriber 인 sink assign 은 둘 다 Cancellable 프로토콜을 준수하고 있기 때문에 cancel()메소드를 통해 취소가 가능합니다.

sub?.cancel()

만약 내장형이 아니라 커스텀 subscriber를 사용하고 있다면 처음 퍼블리셔를 구독할 때 퍼블리셔가 보내는 Subscription 객체를 저장하고 있다가 원할 때 cancel() 메소드를 호출하면 됩니다. 이 때, 반드시 커스텀 subscriber는 Cancellable 프로토콜을 구현하고 있어야 합니다.

참고

--

--

J_sung_0o0

Apple WWDC 19 & 20 Winner (The 1st two-time winner of all time from South Korea)