안녕하세요 !
이번에는 TCA Side Effect 주제를 다뤄보려고 합니다
이번 포스트에서는 다음 내용을 다룰 예정입니다:
- TCA에서 Side Effect의 개념
- EffectTask를 사용한 Side Effect 구현
- 비동기 작업 처리
- 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:) 메소드를 활용하여 리소스를 효율적으로 관리할 수 있어요
이상으로 포스팅 마무리 하겠습니다.
.
.
.
감사합니다.