일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- ios
- SeSAC
- swift 6
- SwiftUI
- 카카오뱅크 ios
- Tuist
- 네트워크 통신
- realm
- Tuist Swift
- GCD
- Swift Tuist
- xcode
- swift db
- RxSwift
- KeyPath
- swift 5.9
- observable
- JSON
- ios database
- swift
- Subject
- arc
- ios swiftdata
- ribs
- swift database
- swiftdata
- Firebase
- Combine
- Firebase Analytics
- Subscribe
- Today
- Total
천원의 개발
iOS Tuist 프로젝트에 적용하기 본문
안녕하세요. 천원입니다.
최근 iOS 개발 트렌드에서 가장 핫한 'Modular Architecture'을 도입하기 위한 도구인 Tuist를 학습하고자 이 글을 작성합니다.
Tuist를 처음 접해보신 분들도 프로젝트에 적용할 수 있도록 진행하겠습니다.
Tuist
Xcode의 프로젝트를 Swift로 생성, 관리할 수 있도록 도와주는 CLI 도구입니다. Swift를 사용해서 프로젝트를 관리하기 때문에 우리가 .xcodeproj, .xcworkspace 같은 파일들로부터 발생하는 Git conflict에 대한 걱정이 필요 없죠. 또한 관리 측면에서 더 많은 개발 편의성을 제공해 준다고 합니다.
성능적인 개선 또한 존재하는데 모듈을 static framework 형태로 만들게 되면 dynamic link가 감소하게 되고 launch time을 감소할 수 있으며 모듈 단위로 빌드가 가능하니 빌드 시간의 감소 또한 큰 이점이라고 생각합니다.
Tuist 도입에 따른 앱 구조의 변화
요기요 기술 블로그에서 확인한 요기요 앱의 구조 변화를 한번 살펴보겠습니다. 먼저 Tuist 도입 이전의 구조입니다.
APP 모듈에 모든 Feature가 담겨져 있고, 각 기능에 공통적으로 필요한 기능 모듈들이 작게 나누어져 있는 형태입니다. 다음은 Tuist 도입 후 구조의 변화를 살펴보겠습니다.
앱에서 각 Featrue들을 분리시킨뒤 APP target은 각 Feature를 Coordinate하는 역할만 담당하는 것으로 APP은 Feature만 바라보고 Feature들은 각자가 필요한 모듈을 의존해 기능을 사용하는 방식입니다. 조금 더 자세한 요기요의 Tuist 적용기는 기술블로그를 통해 확인해 보셔도 좋을 것 같아요.
Tuist 공식문서 튜토리얼 진행하기
Tuist는 CLI 툴이니 터미널 명령어를 통해서 설치가 가능합니다. 아래는 설치 명령어입니다.
curl -Ls https://install.tuist.io | bash
삭제하기
curl -Ls https://raw.githubusercontent.com/tuist/tuist/main/script/uninstall | bash
설치가 완료되었다면 프로젝트를 만들어 줄 폴더를 생성해 줍니다.
mkdir 폴더명
cd 폴더명
프로젝트 init
tuist init --platform ios // UIkit
tuist init --platform ios --template swiftui // SwiftUI
여기까지 하셨다면 이제 init 한 폴더에 어떤 파일들이 생성되었는지 tree를 통해 확인해 봅시다. 만약 tree가 없다면 brew를 통해 설치해 줍니다.
brew install tree // 설치
tree .
다음으로 프로젝트를 editing 해봅시다.
tuist edit
여기서 가장 중요한 Project 파일을 확인할 수 있는데 우리는 Project파일을 통해서 해당 프로젝트의 setting이 가능합니다.
코드를 확인해 보시면 Project+Templates 내부에 작성된 app 메서드를 통해서 프로젝트를 생성해주고 있는 모습입니다.
Templates 내부도 확인해 보면
app 메서드가 Project 구조체를 return 하는 모습입니다. 우리는 여기 Templates을 사용해서 Project를 생성하지 말고 공식 문서에 있는 예시와 함께 만들어 주겠습니다.
let infoPlist: [String: InfoPlist.Value] = [:]
let project = Project(
name: "MyApp",
organizationName: "MyOrg",
targets: [
Target(
name: "MyApp",
platform: .iOS,
product: .app,
bundleId: "io.tuist.MyApp",
infoPlist: .extendingDefault(with: infoPlist),
sources: ["Sources/**"],
resources: ["Resources/**"],
headers: .headers(
public: ["Sources/public/A/**", "Sources/public/B/**"],
private: "Sources/private/**",
project: ["Sources/project/A/**", "Sources/project/B/**"]
),
dependencies: [
/* Target dependencies can be defined here */
/* .framework(path: "framework") */
]
),
Target(
name: "MyAppTests",
platform: .iOS,
product: .unitTests,
bundleId: "io.tuist.MyAppTests",
infoPlist: .extendingDefault(with: infoPlist),
sources: ["Tests/**"],
dependencies: [
.target(name: "MyApp")
]
)
]
)
공식문서의 sample 코드에서 InfoPlist만 추가로 생성해준 코드입니다.
간략하게 보자면 MyApp 이라는 이름에 2개의 Target이 들어가는 프로젝트이며 하나의 target은 App 그리고 unitTests target인 MyAppTests가 들어가 있는 모습입니다.
이제 Project 수정이 완료되었으니 프로젝트를 실행해 보겠습니다.
터미널에서 control + c 를 통해서 Manifests를 종료시켜 주고 fetch와 generate 명령어로 실행을 시켜줍니다.
tuist fetch // 수정된 정보 받아오기
tuist generate // 실행
그러면 Sources/**" does not exist. 머시기 에러가 발생하는데 이유는 우리가 Target 구조체 생성시에 사용한다고 해둔 위치에 Sources파일과 Resources 파일이 존재하지 않아서 발생하는 오류입니다. 이런식으로 설정을 수정하고 휴먼에러가 종종 발생하는데 에러 메세지가 친절하게 되어있어서 금방 해결할 수 있습니다. 프로젝트 폴더에 Sources와 Resources, Tests 폴더를 생성해 줍니다.
그리고 generate를 해주면 정상적으로 실행되는 모습입니다.
참고로 generate를 실행하게 되면 .xcodeproj, .xcworkspace 파일이 생성되지만 숨겨진 파일을 확인해 보면 .gitignore파일이 자동으로 생성되게 되고 내부에 .xcodeproj, .xcworkspace 포함되어 있어서 자동으로 git에서 추적하지 않음을 확인할 수 있습니다.
이제 프로젝트를 확인해 보면 우리가 Project파일에 설정한 대로 Target과 BundleID 등이 정상적으로 들어간 모습입니다. 그런데 Resources 폴더 와 Sources 폴더 내부에 아무것도 없어서 Xcode에 보이지 않는 모습이라 우리는 Add Files를 통해서 Xcode에 추가해 줍니다. 그러면 우리가 정상적으로 사용할 수 있는 프로젝트 완성입니다.
여기까지가 튜토리얼이었습니다. 그런데 우리는 사실 하나의 프로젝트만 관리 하자고 Tuist를 사용하려는게 아니잖아요. 다음 편에서는 Tuist를 사용해서 여러 프로젝트를 한번에 관리하고 SPM을 사용하는 방법을 알아보겠습니다.
'iOS&Swift🍎 > Swift' 카테고리의 다른 글
Swift ReactorKit Pulse 기능을 학습하기 위한 과정 (0) | 2024.06.27 |
---|---|
Swift Clean Architecture 정리 (1) | 2023.11.23 |
Swift RIBs RootRIB 설정하기 (0) | 2023.09.09 |
Swift RIBs 튜토리얼 (with StoryBorad) (0) | 2023.08.26 |
Swift Adapter (0) | 2023.08.11 |