본문 바로가기
Swift

Swift에서 TCA 아키텍처를 활용한 UIKit과 Combine을 사용한 Counter 예제

by mr.conan 2023. 6. 15.
728x90
반응형

소개: 이번 블로그 포스트에서는 Swift에서 TCA (The Composable Architecture) 아키텍처를 UIKit과 Combine을 함께 활용하여 Counter 예제를 구현해보겠습니다. TCA는 구성 가능성과 불변성에 중점을 둔 현대적인 아키텍처 패턴으로, Combine을 함께 사용하여 상태 관리와 이벤트 처리를 효율적으로 다룰 수 있습니다. 이 예제를 통해 TCA, UIKit, 그리고 Combine을 함께 사용하는 방법을 알아보겠습니다.

 

TCA 구현: 1단계: 상태(State) 정의 Counter 예제에서는 카운트 값을 저장하는 상태를 정의합니다. Combine의 @Published 프로퍼티 래퍼를 사용하여 변경 가능한 상태를 만들 수 있습니다:

import Combine

class CounterState: ObservableObject {
    @Published var count: Int = 0
}

2단계: 액션(Action) 정의 Counter 예제에서는 증가 및 감소 액션을 정의합니다. Combine의 PassthroughSubject을 사용하여 액션을 생성하고 처리할 수 있습니다:

import Combine

enum CounterAction {
    case increase
    case decrease
}

class CounterStore: ObservableObject {
    @Published private(set) var state = CounterState()
    private var cancellables = Set<AnyCancellable>()
    private let actionSubject = PassthroughSubject<CounterAction, Never>()
    
    init() {
        actionSubject
            .sink { [weak self] action in self?.reduce(action) }
            .store(in: &cancellables)
    }
    
    func send(_ action: CounterAction) {
        actionSubject.send(action)
    }
    
    private func reduce(_ action: CounterAction) {
        switch action {
        case .increase:
            state.count += 1
        case .decrease:
            state.count -= 1
        }
    }
}

3단계: 뷰(View) 구성 Counter 예제에서는 UILabel과 버튼(UIButton)을 사용하여 카운트 값을 표시하고 증가/감소 액션을 처리하는 뷰를 구성합니다. UIKit과 Combine을 함께 사용하여 UI 업데이트 및 액션 처리를 구현합니다.

import UIKit
import Combine

class CounterViewController: UIViewController {
    @IBOutlet private weak var countLabel: UILabel!
    @IBOutlet private weak var increaseButton: UIButton!
    @IBOutlet private weak var decreaseButton: UIButton!
    
    private var counterStore = CounterStore()
    private var cancellables = Set<AnyCancellable>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        bindToStore()
        setupButtons()
    }
    
    private func bindToStore() {
        counterStore.$state
            .map { String($0.count) }
            .assign(to: \.text, on: countLabel)
            .store(in: &cancellables)
    }
    
    private func setupButtons() {
        increaseButton.addTarget(self, action: #selector(increaseButtonTapped), for: .touchUpInside)
        decreaseButton.addTarget(self, action: #selector(decreaseButtonTapped), for: .touchUpInside)
    }
    
    @objc private func increaseButtonTapped() {
        counterStore.send(.increase)
    }
    
    @objc private func decreaseButtonTapped() {
        counterStore.send(.decrease)
    }
}

결론: 이 블로그 포스트에서는 TCA 아키텍처를 Swift에서 UIKit과 Combine과 함께 사용하여 Counter 예제를 구현하는 방법을 알아보았습니다. TCA는 상태 관리와 이벤트 처리를 효율적으로 다루기 위한 강력한 도구이며, UIKit과 Combine을 함께 사용하면 UI 업데이트와 액션 처리를 쉽게 구현할 수 있습니다. 이를 통해 유지보수성이 높고 확장 가능한 애플리케이션을 개발할 수 있습니다.

 

 

테스트코드 작성하기

2023.07.27 - [Swift] - Swift TCA Counter 예제 CounterStore 테스트하기

728x90
반응형