SwiftUI - TCA Side Effect

CodeCat·2024년 9월 7일

IOS SwiftUI TCA

목록 보기
7/20

안녕하세요 !

이번에는 TCA Side Effect 주제를 다뤄보려고 합니다

이번 포스트에서는 다음 내용을 다룰 예정입니다:

  • TCA에서 Side Effect의 개념
  • EffectTask를 사용한 Side Effect 구현
  • 비동기 작업 처리
  • Side Effect의 취소와 관리

그럼 본격적으로 시작해볼까요?

TCA Side Effect

TCA에서 Side Effect는 EffectTask라는 타입으로 표현되며 EffectTask는 비동기 작업을 수행하고 그 결과를 Action으로 변환하여 다시 시스템에 전달하는 역할을 합니다.

struct MyFeature: ReducerProtocol {
    struct State {
        var counter: Int = 0
    }
    
    enum Action {
        case incrementCounter
        case delayedIncrement
        case delayedIncrementComplete
    }
    
    func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
        switch action {
        case .incrementCounter:
            state.counter += 1
            return .none
            
        case .delayedIncrement:
            return .task {
                try await Task.sleep(nanoseconds: 1_000_000_000)  // 1초 대기
                return .delayedIncrementComplete
            }
            
        case .delayedIncrementComplete:
            state.counter += 1
            return .none
        }
    }
}

예제 설명

  • .incrementCounter을 통한 카운터 증가
  • .delayedIncrement 액션은 1초 후에 카운터를 증가시키는 Side Effect를 생성합니다.
  • .delayedIncrementComplete 액션은 지연된 증가 작업이 완료되었을 때 실행됩니다.

비동기 작업 처리

TCA에서는 EffectTask.task를 사용하여 비동기 작업을 쉽게 처리할 수 있어요 다음은 네트워크 요청을 시뮬레이션하는 예제입니다

struct NetworkFeature: ReducerProtocol {
    struct State {
        var isLoading: Bool = false
        var data: String?
        var error: Error?
    }
    
    enum Action {
        case fetchData
        case dataResponse(TaskResult<String>)
    }
    
    func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
        switch action {
        case .fetchData:
            state.isLoading = true
            state.error = nil
            return .task {
                await .dataResponse(TaskResult { try await fetchDataFromAPI() })
            }
            
        case .dataResponse(.success(let data)):
            state.isLoading = false
            state.data = data
            return .none
            
        case .dataResponse(.failure(let error)):
            state.isLoading = false
            state.error = error
            return .none
        }
    }
}

func fetchDataFromAPI() async throws -> String {
    // 실제 네트워크 요청 로직
    try await Task.sleep(nanoseconds: 2_000_000_000)  // 2초 대기
    return "Data from API"
}

예제 설명:

  • .fetchData 액션은 데이터 fetch 작업을 시작
  • EffectTask.task를 사용하여 비동기 네트워크 요청을 수행
  • .dataResponse 액션은 성공 또는 실패 결과를 처리

SwiftUI 앱에서 TCA - Side Effect를 잘 활용하게 된다면 EffectTask를 통해 비동기 작업을 쉽게 처리하고, .cancellable(id:)와 .cancel(id:) 메소드를 활용하여 리소스를 효율적으로 관리할 수 있어요

이상으로 포스팅 마무리 하겠습니다.

.
.
.

감사합니다.

profile
코드와 고양이의 만남

0개의 댓글