Tuist를 활용한 모듈화
🤔 모듈화?
🙋♂️
하나의 큰 프로그램을 여러 개의 작은 부분(모듈)로 나누는 과정입니다.
각 모듈은 독립적이며,
서로 다른 역할과 책임을 수행해야 합니다.
🤔 모듈화의 필요성
🙋♂️
그러면 모듈화는 왜 하는 것일까요?
- 유지보수: 나누어진 부분에서 수정하면 되기 때문
- 재사용성: 만들어둔 모듈을 다른 프로젝트에서 재사용이 가능합니다.
- 협업: 여러 사람이 동시에 각각의 모듈을 개발할 수 있어, 팀 작업이 더 효율적입니다.
iOS 개발을 하다 보면, 프로젝트가 커질수록 코드의 유지보수성과 확장성을 염두한다면, 모듈화의 필요성을 자연스럽게 깨닫게 됩니다.
여러 기능이 엮어 있는 프로젝트 경우에
모듈화를 통해 코드 간의 결합도를 낮추고, 각 모듈이 독립적으로 동작함으로써,
위에 3가지뿐만 아니라 더 많은 장점을 얻고자 하는 것입니다.
🤔 Tuist는 뭐죠?
🙋♂️
Tuist는 iOS 프로젝트를 더 쉽게 관리하고, 특히 모듈화를 진행할 때 강력한 도구를 제공합니다.
프로젝트 구조를 Swift로 관리할 수 있으며, 각 모듈 간의 의존성을 명확히 정의할 수 있습니다.
쉽게 설명하자면, iOS 협업을 하다보면 Git을 사용할 때
xcodeproj 파일의 충돌을 겪게 됩니다.
이러한 충돌을 해결할 수 있는 것이 Tuist입니다.
🤔 들어가기 앞서,
🙋♂️
작은 프로젝트를 계획하면서 클린 아키텍처를 적용하는 것이 생산성에 영향을 줄 수 있다는 생각이 들긴 했습니다.
특히, 작은 프로젝트에서는 복잡한 구조가 오히려 개발 속도를 늦출 수 있다는 점을 체감하게 됩니다.
그러나 클린 아키텍처의 본질은 유지되지만, 팀이나 프로젝트의 특성에 따라 각기 다른 방식으로 적용된다는 것을 간접적으로 느끼게 되었죠.
아직 클린 아키텍처를 실제 프로젝트에 적용한 경험은 없지만, 이론적으로는 이해하고 있습니다.
하지만 클린 아키텍처에 대한 나만의 가치관을 확립하는 과정은 별개의 문제입니다.
이를 위해, 프로젝트를 진행하면서 클린 아키텍처를 직접 적용해 보는 것이 중요하다고 생각하게 되었습니다.
비록 클린 아키텍처를 적용하면서 진행이 느려질 수 있지만,
이 과정을 통해 얻게 될 이해와 경험은 미래의 더 큰 프로젝트에 큰 도움이 될 것이라는 확신이 있습니다.
그래서 볼륨이 작은 이번 프로젝트에 클린 아키텍처를 적용하기로 계획했습니다.
이 프로젝트를 통해 클린 아키텍처의 원칙을 실제 코드로 구현하고, 각 모듈의 역할을 명확히 나누는 과정을 거칠 것입니다.
이를 통해 클린 아키텍처에 대한 나만의 기준을 확립하고, 이를 다양한 상황에 맞게 응용할 수 있는 능력을 기르려고 합니다.
🤔 모듈 분리 계획?
🙋♂️
제가 현재 이해하고 있는 클린 아키텍처에 기반한 구조를 설계하였습니다.
- TestStock(App): 앱의 진입점 및 의존성 조립
- Presentation: UI와 관련된 로직을 처리
- Domain: 비즈니스 로직과 엔티티 관리
- Data: 데이터 처리
A → B: A는 B를 의존한다.
App → ( Presentation → Domain ← Data )
🤔 Tuist 설정 과정
🙋♂️
- tuist version
tuist 버전을 확인할 수 있습니다. 저는 Tuist 4.27.0 버전 기준입니다.
터미널이나 iTerm에서 진행합니다.
- cd ~/Desktop: 데스크탑에서 진행하고자 합니다.
- mkdir 파일이름: 파일을 생성합니다.
- Tuist 프로젝트를 생성할 때 빈 폴더에서 진행되어야 합니다.
- cd 생성한파일: 파일 이동합니다.
- tuist init --platform ios: SwiftUI가 Default인 Xcode프로젝트가 생성됩니다.
- tuist edit: 프로젝트 세팅을 시작합니다.
- 아래의 사진처럼 나타날 것입니다.
이제 공식문서의 프로젝트 구조 샘플을 응용해서 구조를 변경합니다.
- Move files to destination: Manifest 하위로 Projects파일 아래에 기존에 생겼던 파일을 옮겨줍니다.
- 주의해야할 점은 프로젝트 별로 Project파일이 꼭 있어야합니다.
- 경로가 바뀌었기 때문에, 기존에 Project파일에서 sources와 resources 경로를 변경해줍니다.
- Projects 안에 워크스페이스가 생성되도록 설정합니다.
- Manifests하위에 workspace.swift를 생성합니다
- tuist generate
원하는 구조로 App모듈이 생성되었습니다.
근데 아까도 말했지만 SwiftUI프로젝트가 생성되었습니다.
저는 UIKit으로 진행되길 원합니다.
어떻게 하면 좋을까요?
저는 SceneDelegate로 진행하고자 합니다.
→ 앱 모듈의 Project파일에 infoPlist를 수정해야합니다.
infoPlist: .extendingDefault(
with: [
"UILaunchStoryboardName": "LaunchScreen.storyboard",
"UIApplicationSceneManifest": [
"UIApplicationSupportsMultipleScenes": false,
"UISceneConfigurations": [
"UIWindowSceneSessionRoleApplication": [
[
"UISceneConfigurationName": "Default Configuration",
"UISceneDelegateClassName": "$(PRODUCT_MODULE_NAME).SceneDelegate"
],
]
]
],
]
),
아 그리고 infoPlist에 런치스크린 설정만 하고 파일은 안보이실텐데,
그냥 위처럼 파일명을 똑같이 런치스크린 스토리보드를 생성해주면 됩니다. :)
마지막으로 수정되었으니, tuist generate를 해줍니다.
그리고 Sources 파일 하위에
// AppDelegate.swift
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
}
// SceneDelegate.swift
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let viewController = UIViewController()
viewController.view.backgroundColor = .green
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
}
결과는 아래와 같습니다.
이어서 나머지 모듈도 생성하겠습니다.
사실 내부 의존성을 추가할 때 3가지만 생각하면 됩니다.
- Projects하위에 폴더 생성
- Project 파일 생성, 경로설정
- 의존성을 주입이 필요하다면, 해주면 됩니다.
Presentation부터 진행할게요
다시 tuist edit 을 합니다
다음과 같이 설정해줍니다. ( 경로 설정 꼭하기!! )
// Projects/Presentation/Project.swift
import ProjectDescription
let project = Project(
name: "Presentation",
targets: [
.target(
name: "Presentation",
destinations: .iOS,
product: .staticLibrary,
bundleId: "io.tuist.Presentation",
sources: "Sources/**",
dependencies: []
)
]
)
그리고 App모듈에서는 디펜더시를 명시해줍니다.
// Projects/TestStock/Project.swift
dependencies: [
.project(target: "Presentation", path: "../Presentation")
]
옆에 Presentation 파일 하위에 제가 임의로 구조를 만든 것입니다.
프로젝트 생성 시 빈 파일은 표시되지 않기 때문에, 샘플 코드를 추가해 두었습니다.
다시 tuist generate를 하면?!
해당 뷰 컨트롤러를 보시면 아시겠지만 접근제어자를 public을 사용하였습니다.
왜냐하면 다른 모듈에서 해당 코드를 접근하기 위해서는 public 사용하여 다른 모듈에서 접근 가능하도록 합니다.
다른 모듈을 코드를 사용한 것을 확인할 수 있습니다.
나머지 Domain과 Data도 동일하게 반복하면 (디렉토리와 파일은 본인이 판단하에 정의해줍니다.)
아래와 같은 결과를 확인할 수 있습니다.
그리고 이러한 프로젝트 설정을 바탕으로 tuist generate를 한다면,
아래와 같은 구조를 볼 수 있게 됩니다.
앱모듈은 조립하는 역할이기 때문에 DIP를 따르는 구조에 따라,
모든 모듈을 가져와서 의존성 주입을 하도록 판단하였습니다.
정리
Tuist 모듈화에 대해서 알아보았습니다.
세팅하는데 시간을 정말 많이 보냈는데,
시작이 반인 것 같아요 하하..
Reference
https://chanhhh.tistory.com/m/232
https://eunjin3786.tistory.com/618
https://velog.io/@jwoo820/Tuist-프로젝트-만들기-4.17.0