4.1 SwiftUI Binding VS TCA Binding

SwiftUI는 @State, @ObservedObject 등의 프로퍼티 래퍼를 통해 양방향 바인딩을 구현하고, State 관리를 간편하게 할 수 있는 탁월한 기능을 제공합니다. 추가로, @Binding@State 프로퍼티 래퍼와 함께 View 간의 상호작용을 위해 사용되며, 이는 양방향 통신을 가능하게 하는 프로퍼티 래퍼입니다.

SwiftUI의 Binding은 State 변화를 UI에 즉시 반영해주며, 코드 작성이 간결하다는 장점이 있습니다. 다만, State 관리가 복잡해질수록 State 변화에 따른 Side Effects를 관리하는 데 어려움이 있습니다. 이런 이유로, 앱의 전체 비즈니스 로직을 담당하고 내부 State 변화를 관리하는 TCA에서는 SwiftUI의 기본 @Binding 프로퍼티 래퍼로 State 관리를 하기에 적합하지 않을 수 있습니다.

TCA의 Binding은 이러한 문제를 해결하기 위해 고안한 고유의 State 관리 바인딩 도구들을 제공합니다. TCA는 단방향 데이터 흐름 원칙을 따르며, State 변화는 Action을 전송하고 Reducer가 이를 수신하여 로직을 처리합니다. 이로써 State 변화에 따른 Side Effects를 일관되게 관리할 수 있고, State 변화 로직을 명확하게 파악할 수 있어 복잡한 State 관리가 가능합니다. 그러나 간단한 State 변화에 비해 코드가 복잡하며, 각 State 변화에 대해 Action을 정의하고 Reducer에서 이를 처리하는 로직을 작성해야 합니다.

이제 TCA의 Binding 도구가 어떻게 SwiftUI의 Binding처럼 View State를 업데이트하고, 동시에 단방향으로 복잡한 State 관리를 수행할 수 있는지 살펴보겠습니다.

<aside> 💡 SwiftUI의 Binding VS TCA Binding

SwiftUI TCA
장점 - State의 변경이 UI에 즉시 반영

4.2 TCA Binding

TCA의 가장 기본적인 바인딩은 Binding(get:send:) 형태입니다.

두 개의 클로저를 매개변수로 전달받습니다.

예제를 통해 TCA에서 제공하는 Binding에 대해 살펴보겠습니다. 예시로, reducer에는 사용자가 햅틱 피드백을 활성화 했는지 추적하는 도메인 기능이 있다고 가정합니다.

State에는 햅틱 피드백에 대한 Bool 프로퍼티를 정의할 수 있습니다.

struct Settings: Reducer {
  struct State: Equatable {
    var isHapticFeedbackEnabled = true
    /* code */
  }

  /* code */
}

만약 View에서 토글을 사용하여 Store 외부에서 이 State를 조정할 수 있다면, Action의 형태를 정의할 수 있게 됩니다.

struct Settings: Reducer {
  struct State: Equatable { /* code */ }

  enum Action { 
    case isHapticFeedbackEnabledChanged(Bool)
    /* code */
  }

  /* code */
}