SwiftUI - TCA Effect

CodeCat·2024년 9월 7일

IOS SwiftUI TCA

목록 보기
5/20
post-thumbnail

안녕하세요!

이번에는 TCA Effect에 알아보려해요

Effect란 무엇인가?

Effect는 TCA에서 Action의 결과로 발생하는 모든 작업을 나타내는 개념입니다. 특히 비동기 작업이나 외부 시스템과의 상호작용을 다룰 때 중요한 역할을 합니다.

참고로 Effect는 앱의 상태를 직접 변경하지 않고, 비동기 작업을 수행한 후 그 결과를 새로운 Action으로 반환하는 역할을 해요

Effect의 특징

  • 비동기 작업 처리: 네트워크 요청, 데이터 로딩 등 시간이 걸리는 작업을 효과적으로 관리합니다.
  • 부수 효과 분리: 순수한 상태 변경과 부수 효과를 명확히 구분하여 코드의 가독성과 유지보수성을 높입니다.
  • 에러 핸들링: 비동기 작업 중 발생할 수 있는 오류를 체계적으로 처리합니다.
    실행 순서 보장: Effect들은 순차적으로 실행되어 예측 가능한 결과를 제공합니다.

Effect의 활용

Effect를 통해 우리는 복잡한 비동기 로직을 간단하고 명확하게 표현할 수 있습니다.

예를 들어 네트워크 요청을 수행한다고 하면 Effect가 요청을 수행하고 결과 데이터 또는 오류 정보 등을 포함하는 새로운 Action을 생성하여 반환 시킵니다

이 Action은 다시 Reducer에서 받아서 상태 업데이트 로직을 수행하는 거죠

Effect와 Combine

Combine과 Effect 간의 서로 유사한점이 있는데 Publisher와 Effect의 유형이, Subscriber와 Effect의 .run 이 같은 개념이라 생각하시면 됩니다

Effect와 Action

Effect와 Action은 각각 다른 역할을 담당하는데 Action은 이벤트를 캡슐화하며 State를 업데이트 시키지만 Effect는 비동기 작업을 처리하고 그 결과를 다시 Action으로 반환하는 역할을 담당합니다

예를 들어 로그인을 하는 과정을 구조로 설명하면

View(로그인버튼 클릭) ->
Store ->
Reducer에서 Action을 받음 ->
네트워크 통신을 위한 비동기 처리를 위해 Effect .run을 통해 수행 ->
결과 값을 새로운 Action에 담아 반환 ->
다시 Reducer에서 Action을 받음 ->
Action안에서 State 업데이트 시킴 ->
View 업데이트

Effect의 주요 메서드

.none

Effect로 비동기 로직을 처리하고 Effect를 반환해야하는데 아무런 동작을 하고 싶지 않을 때 사용합니다

struct CounterFeature: Reducer {
    
    struct State: Equatable {/* code */}
  
    enum Action {/* code */}
    
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .incrementButtonTapped:
                state.count += 1
                return .none
            case .decrementButtonTapped:
                state.count -= 1
                return .none
        }
    }
}

.send

.none과 달리 Effect 비동기 처리 이후 추가적인 작업이 필요할때 사용 됩니다

// MARK: 로그인 요청,응답 및 로그아웃
case .signIn(let email, let name):
    print("AuthFeature Action signIn 진입")
    return .run { send in
        do {

            let signInRequestModel = SignInRequestModel(email: email)
            let signInResult = try await authClient.signIn(signInRequestModel)

  			await send(.signInResponse(.success(signInResult)))

        } catch(let error as NetworkError) {
            print("AuthFeature Action signIn fail \(error.localizedDescription)")
            await send(.cancelFail(.signIn, " signIn fail \(error.localizedDescription)"))
        }

//                    print("AuthFeature Action signIn \(signInResult?.result_msg ?? "")")
    }
    .cancellable(id: CancelID.signIn)

"await send(.signInResponse(.success(signInResult)))" 에서 볼 수 있듯이 비동기 처리 이후 추가적인 작업을 요청 했습니다 즉 새로운 Action을 반환하는 과정인거죠!

.run

비동기 작업을 래핑하는 메서드 이며 인자로 비동기 클로저를 받아서 실행합니다
즉 .run 안에서 비동기 작업(예 : 네트워크 통신)을 처리하시면 됩니다!

예제 코드는 위에 참고해주세요 !

return .run { send in

Effect에 기본적인 내용들은 여기까지구요 !

이와 관련된 글은 뒤에서 더 깊이 있게 다루도록 하겠습니다

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

.
.
.

감사합니다.

profile
코드와 고양이의 만남

0개의 댓글