본문 바로가기
Swift

Swift TCA와 Swinject를 활용한 Navigation 샘플 만들기

by mr.conan 2023. 7. 20.
728x90
반응형

Step 1: 프로젝트 설정과 기본 환경 구성

  1. Xcode를 열고 새로운 프로젝트를 생성합니다.
  2. "Single View App" 템플릿을 선택하고, 프로젝트 이름을 "TCAWithSwinject"로 지정합니다.

Step 2: Swinject 설치 및 설정

  1. Podfile을 열고 Swinject를 설치합니다.
platform :ios, '13.0'

target 'TCAWithSwinject' do
  use_frameworks!

  pod 'Swinject', '~> 2.7'
  pod 'SwinjectAutoregistration', '~> 2.7'

  # 다른 라이브러리들을 추가할 수도 있습니다.
end

 

Step 3: Navigation 기능을 위한 View와 State 구현

  1. 프로젝트 내에 NavigationState.swift 파일을 생성합니다.
import Foundation
import ComposableArchitecture

// Navigation 상태를 정의합니다.
struct NavigationState {
    var isShowingDetail: Bool
}

// 기본 상태를 생성합니다.
extension NavigationState {
    static var initial: NavigationState {
        NavigationState(isShowingDetail: false)
    }
}

프로젝트 내에 NavigationView.swift 파일을 생성합니다.

import SwiftUI
import ComposableArchitecture

// 뷰를 정의합니다.
struct NavigationView: View {
    let store: Store<NavigationState, NavigationAction>

    var body: some View {
        WithViewStore(self.store) { viewStore in
            VStack {
                Text("Main View")
                Button("Show Detail") {
                    viewStore.send(.showDetailButtonTapped)
                }
            }
            .sheet(isPresented: viewStore.binding(
                get: { $0.isShowingDetail },
                send: NavigationAction.dismissDetail
            )) {
                DetailView(store: self.store)
            }
        }
    }
}

// 액션을 정의합니다.
enum NavigationAction {
    case showDetailButtonTapped
    case dismissDetail
}

// 리듀서를 정의합니다.
let navigationReducer = Reducer<NavigationState, NavigationAction, Void> { state, action, _ in
    switch action {
    case .showDetailButtonTapped:
        state.isShowingDetail = true
        return .none
    case .dismissDetail:
        state.isShowingDetail = false
        return .none
    }
}

 

 

프로젝트 내에 DetailView.swift 파일을 생성합니다.

import SwiftUI
import ComposableArchitecture

// 뷰를 정의합니다.
struct DetailView: View {
    let store: Store<NavigationState, NavigationAction>

    var body: some View {
        WithViewStore(self.store) { viewStore in
            VStack {
                Text("Detail View")
                Button("Dismiss") {
                    viewStore.send(.dismissDetail)
                }
            }
        }
    }
}

 

 

Step 4: Swinject를 활용하여 View와 State 연결하기

  1. 프로젝트 내에 AppContainer.swift 파일을 생성합니다.
import Foundation
import Swinject
import SwinjectAutoregistration
import ComposableArchitecture

class AppContainer {
    let container: Container

    init() {
        self.container = Container()

        self.container.autoregister(
            Store<NavigationState, NavigationAction>.self,
            initializer: Store.init
        ) { r in
            Store(
                initialState: NavigationState.initial,
                reducer: navigationReducer,
                environment: ()
            )
        }

        self.container.register(NavigationView.self) { r in
            NavigationView(store: r.resolve(Store<NavigationState, NavigationAction>.self)!)
        }

        self.container.register(DetailView.self) { r in
            DetailView(store: r.resolve(Store<NavigationState, NavigationAction>.self)!)
        }
    }
}

 

 

Step 5: Swinject를 활용하여 View 연결하기

  1. 프로젝트 내에 ContentView.swift 파일을 생성합니다.
import SwiftUI

struct ContentView: View {
    let navigationView: NavigationView

    var body: some View {
        self.navigationView
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let container = AppContainer()
        return ContentView(
            navigationView: container.container.resolve(NavigationView.self)!
        )
    }
}

 

이상으로, Swift TCA와 Swinject를 활용하여 Navigation 샘플을 만드는 방법을 블로그 형식으로 작성하는 방법을 안내드렸습니다. 추가적으로 필요한 코드를 구현하면서 더 많은 기능과 UI 개선을 진행하실 수 있을 것입니다. 행운을 빕니다!

728x90
반응형