THE STEADY COMPANY
Swift Dependencies 잘 활용하기 cover image

Swift Dependencies 잘 활용하기

추상화를 통해 빌드 시간 절약하기

2025-01-05 19:00

·
  • iOS
  • Dependency Injection

들어가며

TCA를 주력으로 사용하다 보니 swift-dependencies로 의존성을 관리하고 있어요.
프로토콜 방식과 다르게, 구조체+클로저를 통해 의존성을 다루는 방식이에요.

/// 구조체+클로저
@DependencyClient
struct Manager {
  var execute: @Sendable () async throws -> Void
}

protocol Provider {
  func execute() async throws -> Void
}

final class DefaultProvider: Provider {}

의존성 역전이 이렇게 잘 되는 줄 몰랐어요

사실 처음에는 swift-dependencies로 의존성이 제대로 추상화되지 않을 줄 알았어요.
그런데 실제로 써보니 너무 잘 되고 있었어요.

/// AuthClient 모듈
@DependencyClient
public struct AuthClient {
  public var auth: @Sendable () async throws -> Void
}

extension AuthClient: TestDependencyKey {
  public static let testValue = Self()
}

/// AuthClientLive 모듈
extension AuthClient: DependencyKey {
  public static let liveValue = AuthClient(
    auth: { /* 구현 */ }
  )
}

위처럼 모듈을 분리하고, 사용하는 쪽에서 구현체 모듈을 import하면 돼요.


마치며

이 방식을 통해 사이즈가 큰 외부 라이브러리(예: Firebase)를 인터페이스 모듈로 분리해서 활용하고 있어요.
빌드 시간도 줄어들었고, 테스트 환경도 훨씬 깔끔해졌어요.

참고로 isowords의 ApiClient 구조를 보면
실제 프로젝트에서 어떻게 적용하는지 감을 잡을 수 있어요.