개요

SwiftUI의 여러 API는 바인딩을 사용하여 애플리케이션의 상태와 뷰 간에 양방향 통신을 설정합니다. Composable Architecture는 이러한 통신을 애플리케이션의 스토어와 설정할 수 있는 여러 도구를 제공합니다.

임시 바인딩 (Ad hoc bindings)

  1. 상태 정의: 상태를 변경할 수 있도록 도메인에 상태를 정의합니다.

    swift코드 복사
    @Reducer
    struct Settings {
      struct State: Equatable {
        var isHapticsEnabled = true
      }
    }
    
  2. 액션 정의: 상태 변경을 위한 액션을 정의합니다.

    swift코드 복사
    @Reducer
    struct Settings {
      enum Action {
        case isHapticsEnabledChanged(Bool)
      }
    }
    
  3. 리듀서에서 상태 업데이트: 리듀서에서 액션을 처리하여 상태를 업데이트합니다.

    swift코드 복사
    @Reducer
    struct Settings {
      var body: some Reducer<State, Action> {
        Reduce { state, action in
          switch action {
          case let .isHapticsEnabledChanged(isEnabled):
            state.isHapticsEnabled = isEnabled
            return .none
          }
        }
      }
    }
    
  4. 뷰에서 바인딩 생성: 뷰에서 상태를 바인딩하여 토글을 통해 상태를 변경할 수 있도록 합니다.

    swift코드 복사
    struct SettingsView: View {
      @Bindable var store: StoreOf<Settings>
    
      var body: some View {
        Form {
          Toggle(
            "Haptic feedback",
            isOn: $store.isHapticsEnabled.sending(\\.isHapticsEnabledChanged)
          )
        }
      }
    }
    

바인딩 액션 및 리듀서

더 많은 컨트롤이 있는 화면에서 수작업으로 바인딩을 설정하는 것은 번거로울 수 있습니다. 이를 간소화하기 위해 Composable Architecture는 BindableAction과 BindingReducer를 제공합니다.

  1. 상태와 액션 정의: 상태와 액션을 정의합니다.

    swift코드 복사
    @Reducer
    struct Settings {
      @ObservableState
      struct State {
        var digest = Digest.daily
        var displayName = ""
        var enableNotifications = false
        var protectMyPosts = false
        var sendEmailNotifications = false
        var sendMobileNotifications = false
      }
    
      enum Action: BindableAction {
        case binding(BindingAction<State>)
      }
    }
    
  2. 리듀서에서 바인딩 처리BindingReducer를 사용하여 상태 변화를 처리합니다.

    swift코드 복사
    @Reducer
    struct Settings {
      var body: some Reducer<State, Action> {
        BindingReducer()
      }
    }
    
  3. 뷰에서 바인딩 사용: 바인딩을 사용하여 뷰와 상태를 연결합니다.

    swift코드 복사
    struct SettingsView: View {
      @Bindable var store: StoreOf<Settings>
    
      var body: some View {
        Form {
          TextField("Display name", text: $store.displayName)
          Toggle("Notifications", isOn: $store.enableNotifications)
        }
      }
    }
    
    
  4. 추가 기능 구현: 리듀서에서 특정 키 경로에 대한 추가 기능을 레이어링할 수 있습니다.

    swift코드 복사
    var body: some Reducer<State, Action> {
      BindingReducer()
        .onChange(of: \\.displayName) { oldValue, newValue in
          // Validate display name
        }
        .onChange(of: \\.enableNotifications) { oldValue, newValue in
          // Return an authorization request effect
        }
    }
    
  5. 테스트: 바인딩 액션을 테스트할 수 있습니다.

    swift코드 복사
    let store = TestStore(initialState: Settings.State()) {
      Settings()
    }
    
    store.send(\\.binding.displayName, "Blob") {
      $0.displayName = "Blob"
    }
    store.send(\\.binding.protectMyPosts, true) {
      $0.protectMyPosts = true
    }
    

이 가이드는 SwiftUI와 Composable Architecture를 사용하여 바인딩을 설정하고 관리하는 방법을 간소화하고 효율적으로 구현하는 방법을 설명합니다.