맛동산이

SwiftUI) TCA 비동기처리, TaskResult타입 본문

앱/SwiftUI

SwiftUI) TCA 비동기처리, TaskResult타입

진ddang 2024. 8. 8. 15:16

기본적인 비동기

var body: some ReducerOf<Self> {
        Scope(state: \\.login, action: \\.login) {
            Login()
        }
        Reduce<State, Action> { state, action in
            switch action {
	            case .test1:
		            return .run { 여기 안에서 비동기를 처리 해준다. }
		            
			        case .fetch(.success):
								return .none			        
			        case .fetch(.failure):
				        return .none

TCA에서는 비동기 처리를 해줄때 action에서 .run으로 한다는 사실은 알고 있다.

이때 Action에서 해당 비동기를 받은 다음 다시한번 Action으로 체이닝해서 다시 처리를 해줘야 한다.

이때 TaskResult라는 데이터 타입을 통해서 해결해준다.

TaskResult

taskResult는 비동기처리의 성공 실패를 다루는 타입이다.

예시

1. Action정의

enum FeatureAction: Equatable {
  case factButtonTapped
  case factResponse(TaskResult<String>)
}

와 같이 해당 리스폰스에 대해서 정의를 해두고, 어떠한 타입의 결과값을 던질지 정의해둔다.

2. 사용 부분

case .factButtonTapped:
  return .task {
    await .factResponse(
      TaskResult { try await environment.numberFact(state.number) }
    )
  }

case .factResponse(.success(fact)):
  // do something with fact

case .factResponse(.failure):
  // handle error

...
}

실제로 api를 쏘고 난 뒤의 결과값을 factResponse에 넘기면,

해당 케이스 자체에서 결과를 케이스를 나눌수 있는데 위의 예시에서는 에러를 처리하지는 않았기 때문에 에러를 처리하는 케이스를 다시 보자면 다음과 같다.

case .task:
    state.isLoading = true
    return .run { send in
        for try await result in try await self.authenticationClient.listenAuthState() {
            await send(.listenAuthStateResponse(.success(result)))
        }
    } catch: { error, send in
        await send(.listenAuthStateResponse(.failure(error)))
    }

이렇게 try catch문으로 에러와 데이터를 success와 fail에 담에서 보내면 된다.

반응형