
안녕하세요 !
이번에는 TCA Dependency 주제로 이야기해보려합니다 !
의존성 관리는 앱의 유지보수성과 테스트 용이성을 위해서는 꼭 알아두어야할 내용인데요
TCA의 Dependency 기능을 통해 외부 서비스나 API와의 상호작용을 어떻게 추상화하고 관리할 수 있는지 살펴보도록 할게요
TCA에서 의존성 관리는 DependencyKey 프로토콜과 @Dependency 프로퍼티 래퍼를 통해 이루어집니다
먼저, DependencyKey 프로토콜을 구현하여 의존성을 정의
private enum APIClientKey: DependencyKey {
static let liveValue = APIClient.live
static let testValue = APIClient.mock
}
liveValue는 실제 앱에서 사용될 구현을, testValue는 테스트에서 사용될 모의 구현을 나타내요
extension DependencyValues {
var apiClient: APIClient {
get { self[APIClientKey.self] }
set { self[APIClientKey.self] = newValue }
}
}
이 코드를 통해 apiClient라는 이름으로 우리의 의존성에 접근할 수 있습니다
이제 정의한 의존성을 실제로 사용해볼건데요 TCA의 Reducer에서 다음과 같이 의존성을 주입받을 수 있어요
struct Feature: Reducer {
@Dependency(\.apiClient) var apiClient
func reduce(into state: inout State, action: Action) -> Effect<Action> {
switch action {
case .buttonTapped:
return .run { send in
let response = try await apiClient.fetchData()
await send(.dataLoaded(response))
}
// ... 기타 케이스들
}
}
}
@Dependency 프로퍼티 래퍼를 사용하여 apiClient를 주입받고 있고 buttonTapped 액션이 발생했을 때, 이 apiClient를 사용하여 데이터를 비동기적으로 가져올 수 있어요
테스트나 프리뷰에서는 실제 API 대신 모의 구현을 사용해야 할 때
let store = TestStore(
initialState: Feature.State(),
reducer: Feature()
) {
$0.apiClient = .mock
}
이 코드는 테스트용 스토어를 생성할 때 apiClient를 모의 구현으로 오버라이드하고 있습니다.
모의 구현 오버라이드와 관련해서는 다음 포스팅에서 더 다뤄보도록 할게요!
이상으로 포스팅 마무리 하겠습니다.
.
.
.
감사합니다.