[swift] Swift Sourcery를 활용한 VIPER 아키텍처 구현

VIPER는 iOS 애플리케이션 개발에 사용되는 아키텍처 중 하나로써, 모듈화와 테스트 용이성을 강조하는 특징이 있습니다. VIPER는 해당 모듈을 다양한 컴포넌트로 분리하고, 각 컴포넌트들이 단일 책임을 가지도록 구성됩니다.

Sourcery는 Swift 코드를 생성하기 위한 템플릿 기반 코드 생성 도구입니다. Sourcery를 사용하면 VIPER의 각 컴포넌트에 대한 기본 코드를 자동으로 생성할 수 있습니다. 따라서, VIPER 아키텍처를 구현할 때 Sourcery를 활용하면 반복적이고 지루한 작업을 줄여줄 수 있습니다.

Sourcery 설정

Sourcery를 사용하기 위해 먼저 프로젝트에 Sourcery를 설치해야 합니다. 다음과 같이 brew를 사용하여 설치할 수 있습니다:

brew install sourcery

Sourcery를 설치한 뒤, sourcery.yml이라는 파일을 프로젝트 루트 디렉토리에 생성합니다.

sources:
  - path/to/your/project

templates:
  - path/to/your/templates

위의 설정 파일에서 path/to/your/project는 소스 코드가 있는 디렉토리 경로, path/to/your/templates는 Sourcery 템플릿 파일이 있는 경로를 나타냅니다.

VIPER 모듈 생성

Sourcery와 템플릿을 사용하여 VIPER 모듈을 생성해보겠습니다.

먼저, Sourcery로 사용할 템플릿 파일을 작성합니다. 예를 들어, viper.template이라는 템플릿 파일을 생성하여 아래와 같은 내용을 작성할 수 있습니다:

// sourcery:inline:ViperModuleTemplate
import Foundation
import UIKit

protocol ViperViewProtocol: class {

}

protocol ViperPresenterProtocol: class {

}

protocol ViperInteractorProtocol: class {

}

protocol ViperRouterProtocol: class {

}

class ViperView: UIViewController, ViperViewProtocol {

}

class ViperPresenter: ViperPresenterProtocol {

    weak var view: ViperViewProtocol?
    var interactor: ViperInteractorProtocol?
    var router: ViperRouterProtocol?

    init(view: ViperViewProtocol) {
        self.view = view
    }

}

class ViperInteractor: ViperInteractorProtocol {

    weak var presenter: ViperPresenterProtocol?

    init(presenter: ViperPresenterProtocol) {
        self.presenter = presenter
    }

}

class ViperRouter: ViperRouterProtocol {

}
// sourcery:end

위의 템플릿에는 VIPER 아키텍처의 각 컴포넌트를 정의한 코드가 포함되어 있습니다. Sourcery는 sourcery:inlinesourcery:end 주석으로 둘러싸인 영역을 인식하고, 이 영역에 해당하는 코드를 생성합니다.

템플릿 파일을 작성한 뒤, VIPER 모듈을 생성하기 위해 다음과 같이 커맨드라인에서 Sourcery를 실행합니다:

sourcery

Sourcery는 설정 파일에 지정된 디렉토리에서 .swift 파일을 찾고, 해당 파일들을 템플릿 파일과 매칭하여 코드를 자동으로 생성합니다. VIPER 모듈에 대한 코드가 자동으로 생성되고, 이는 해당 컴포넌트만의 파일로 저장됩니다.

VIPER 모듈 사용

Sourcery를 사용하여 생성된 VIPER 모듈을 사용하는 방법은 다음과 같습니다:

class MyModuleViewController: ViperView {

    var presenter: ViperPresenter?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        presenter = ViperPresenter(view: self)
        
        presenter?.viewDidLoad()
    }

    // ViperViewProtocol 메서드 구현
}

let myModuleViewController = MyModuleViewController()
let myModulePresenter = MyModulePresenter(view: myModuleViewController)
let myModuleInteractor = MyModuleInteractor(presenter: myModulePresenter)
let myModuleRouter = MyModuleRouter()

myModuleViewController.presenter = myModulePresenter
myModulePresenter.interactor = myModuleInteractor
myModulePresenter.router = myModuleRouter

위의 코드에서는 생성된 VIPER 모듈을 사용하여 MyModuleViewController와 해당 컴포넌트를 생성하고 연결하는 과정을 보여줍니다. 이렇게 생성된 모듈은 각 컴포넌트가 단일 책임을 가지고 독립적으로 테스트할 수 있습니다.

결론

Sourcery를 사용하여 VIPER 아키텍처를 구현하면 개발자는 반복 작업을 줄이고 모듈화된 코드를 효율적으로 생성할 수 있습니다. VIPER 아키텍처의 각 컴포넌트에 대한 기본 코드를 자동으로 생성함으로써 생산성을 향상시키고, 유지보수성을 향상시킬 수 있습니다.

더 자세한 내용은 아래 링크를 참조하세요: