Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] Combine의 Subscriber 사용 방법 본문

iOS Combine (SwiftUI)

[iOS - SwiftUI] Combine의 Subscriber 사용 방법

jake-kim 2022. 9. 19. 23:27

목차) Combine - 목차 링크

Susbscriber

https://developer.apple.com/documentation/combine/subscriber

  • protocol이며 이 프로토콜을 준수하는 subscriber 인스턴스를 만들면, 이 subscriber로 다른 publisher를 구독하여 사용
    • 구독했을때 처리가 이 Subscriber 구현체에서 처리
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public protocol Subscriber : CustomCombineIdentifierConvertible {
    associatedtype Input
    associatedtype Failure : Error

    func receive(subscription: Subscription)
    func receive(_ input: Self.Input) -> Subscribers.Demand
    func receive(completion: Subscribers.Completion<Self.Failure>)
}
  • 일반적인 publisher - subscribe 처리
    • sink를 이용하여 구독하여 처리
let publisher = [1,2,3].publisher
publisher
  .sink { print("출력? \($0)") }
  • 처리가 복잡한 경우 별도의 subscriber 인스턴스에서 처리하고 싶은 경우, Subscriber 이용
class MySubscriber: Subscriber {
  /// 성공 타입
  typealias Input = Int
  /// 실패 타입
  typealias Failure = Never
  
  func receive(_ input: Int) -> Subscribers.Demand {
    print("데이터 수신: \(input)")
    return .none
  }
  
  func receive(subscription: Subscription) {
    print("데이터 구독 시작")
    subscription.request(.unlimited) // 구독할 데이터의 갯수를 제한하지 않는 것
  }
  
  func receive(completion: Subscribers.Completion<Never>) {
    print("모든 데이터 발행 완료")
  }
}

let myPublisher = [1,2,3].publisher
let subscriber = MySubscriber()
myPublisher
  .subscribe(subscriber)


/*
데이터 구독 시작
데이터 수신: 1
데이터 수신: 2
데이터 수신: 3
모든 데이터 발행 완료
*/

AnySubscriber

  • 타입이 제거된 subscriber (가장 추상적인 Subscriber 형태)
    • 세부 정보를 외부에 숨겨서, 결합도를 낮추는데 사용

ex) AnySubscriber의 가장 기본 기능 사용 방법

let subscriber = AnySubscriber<Int, Never>(
  receiveSubscription: { sub in
    print("receiveSubscription: \(sub)")
  },
  receiveValue: { v1 in
    print("receiveValue: \(v1)")
    return .max(1)
  },
  receiveCompletion: { _ in
    print("receiveCompletion")
  }
)

[1, 2]
  .publisher
  .subscribe(subscriber)

// receiveSubscription: [1, 2]

* 참고

https://developer.apple.com/documentation/combine/subscriber

Comments