안녕하세요.
이번엔 TCA의 Dependency에 대해 알아볼게요.
(TCA 1.2.0 기준으로 작성했으며, 전체 코드는 여기를 봐주세요!)
# 개요
TCA에서는 기능(Reducer)에서 필요한 의존성(Dependency) 주입을 쉽게 처리할 수 있습니다.
[참고] TCA의 의존성 관리 시스템
TCA는 pointfreeco에서 만든 swift-dependencies 라이브러리를 사용하고 있습니다.
실제로 TCA가 제공하는 의존성 모듈들은 swift-depdendencies 라이브러리에서 나온 것입니다.
Document가 잘 되어 있으니 한번 읽어보시는 것을 추천해요.
이번 글에선 TCA가 제공하는 Dependency 모듈을 Reducer에 어떻게 주입하는지에 대해 알아볼게요.
(커스텀 모듈을 주입하는 방법은 다음 글에서 알아볼게요!)
# 예시
TCA는 기본으로 다양한 의존성 모듈을 제공하고 있습니다ㅎㅎ
이 중에서도 가장 대표적으로 사용되는 UUID, Date, Clock 모듈을 사용해서 현재 시간을 출력하고 UUID를 생성하며, 1초 후에 또 다른 UUID를 생성하는 예제를 만들어 볼게요.
## Dependency Injection
아래는 의존성 주입 전 코드입니다. 여기에 살을 붙여볼게요.
의존성을 주입할 때, TCA에서는 @Dependency라는 propertyWrapper를 사용하고 keyPath로 어떤 모듈을 사용할지 결정합니다.
예를 들어, 아래와 같은 코드를 통해 의존성을 주입할 수 있습니다.
[참고] 의존성 모듈은 DependencyValues 타입입니다.
위 코드에서 주목할 점은, @Dependency 변수는 DependencyValues를 확장한 변수 중 하나라는 점이에요.
Dependency propertyWrapper 내부 코드를 살펴보면, keyPath로 DependencyValues 타입의 인스턴스를 가져오는 것을 알 수 있어요.
예시로 든 uuid의 경우, DependencyValues를 확장한 변수로 선언되어 있어 keyPath로 가져올 수 있었던 것입니다.
커스텀 모듈을 의존성 주입하고 싶으면, 해당 모듈을 DependencyValues를 확장해서 선언해야 합니다.
이와 관련된 자세한 내용은 다음 글에서 다룰게요!
Reducer에서 @Dependency를 사용해서 의존성 주입된 모듈을 선언하면 해당 기능을 사용할 수 있습니다.
[참고] TCA가 제공하는 의존성 모듈 사용법은 아래 문서 참고해 주세요!
https://pointfreeco.github.io/swift-dependencies/1.0.0/documentation/dependencies/dependencyvalues/
[주의] @Dependency 변수는 static 프로퍼티로 선언하면 안 됩니다.
static 프로퍼티는 lazy 하기 때문에, 의존성 주입 후 해당 모듈을 처음으로 사용할 때 capture 됩니다.
이로 인해 의도하지 않은 동작이 발생할 수 있기 때문에 아래처럼 @Dependency 변수는 static 프로퍼티로 선언되어선 안됩니다.
## Overriding dependeny
dependency 수식어를 통해 의존성 모듈을 손쉽게 교체할 수 있습니다.
이를 통해 하위 Reducer에서만 다른 의존성 모듈을 사용하거나 mock 테스트를 수행하는 것도 간단해집니다.
예를 들어서, TCA의 UUID 모듈 대신 0부터 1씩 순차적으로 증가하는 UUID 생성 모듈을 사용하고 싶다면, 다음과 같이 dependency 수식어로 사용할 모듈을 교체할 수 있습니다.
# 참고
이번 글은 여기서 마무리.
'SwiftUI' 카테고리의 다른 글
@ViewBuilder는 언제 사용할까? (0) | 2023.12.19 |
---|---|
TCA(10) : Custom Dependency (1) | 2023.10.10 |
WebView 당겨서 새로고침(Pull to Refresh) 기능 추가하기 (0) | 2023.09.05 |
TCA(8) : Binding (1) | 2023.08.09 |
TCA(7) : 0.54.0 -> 1.0.0 업데이트 (0) | 2023.08.07 |