[Swift] Combine

Swiftios
avatar
2025.02.04
·
3 min read

Combine

  1. Combine 프레임워크

    • Apple에서 제공하는 반응형 프로그래밍(Reactive Programming) 프레임워크

    • 데이터를 비동기적으로 처리하고, 이벤트를 선언적으로 처리하는 데 사용

  2. 주요 개념

    • Publisher: 데이터를 제공하는 주체

    • Subscriber: 데이터를 수신하고 처리하는 주체

    • Operators: 데이터를 변환하거나 필터링하는 중간 연산자

  3. Combine의 흐름: Publisher -> Operator -> Subscriber

  4. 예제

    import Combine
    
    // Publisher 생성
    let numbers = [1, 2, 3, 4, 5].publisher
    
    // Subscriber를 통해 값 출력
    numbers
        .map { $0 * 2 }  // 값 변환
        .sink { print($0) }  // 값 출력

직접 구현해보기

  1. Combine 기본 구현

    1. 간단한 Publisher와 Subscriber 만들기: 배열 [10, 20, 30, 40, 50]Publisher로 생성하고, 각 값을 2배로 변환한 후 출력하세요

      import Combine
      
      let numbers = [10, 20, 30, 40, 50].publisher
      
      numbers
          .map { $0 * 2}
          .sink { print($0) }
    2. Just Publisher 사용: 단일 값 100을 제공하는 Just 를 사용하여 값을 변환(+50)하고 출력하세요

      import Combine
      
      let number = Just(100)
      
      number
          .map { $0 + 50 }
          .sink { print($0) }
  2. Combine으로 비동기 데이터 처리

    1. URLSession과 Combine 사용

      import Combine
      import Foundation
      
      struct Todo: Codable {
          let title: String
      }
      
      let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
      var cancellable: AnyCancellable?
      
      cancellable = URLSession.shared.dataTaskPublisher(for: url)
          .map { $0.data }
          .decode(type: Todo.self, decoder: JSONDecoder())
          .receive(on: DispatchQueue.main)
          .sink(
              receiveCompletion: { completion in 
                  switch completion {
                  case .finished:
                      print("Complete")
                  case .failure(let error):
                      print("[Error] \(error)")
                  }
              },
              receiveValue: { todo in 
                  print("Title: \(todo.title)")
              }
          )
    2. Timer Publisher 사용

      • 1초마다 현재 시간을 출력하는 Combine 타이머를 생성하세요

      • 5초 후에는 구독을 취소하세요

      import Combine
      import Foundation
      
      let timer = Timer.publish(every: 1.0, on: .main, in: .common)
          .autoconnect()
      var cancellable: AnyCancellable?
      
      let formatter: DateFormatter = {
          let f = DateFormatter()
          f.timeStyle = .medium
          return f
      }()
      
      cancellable = timer
          .sink { time in
              print(formatter.string(from: time))
          }
      
      DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
          cancellable?.cancel()
      }






- 컬렉션 아티클