Notice
Recent Posts
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- 클린코드
- UIKit
- hackerrank
- five lines of cdde
- Swift코딩테스트
- IOS
- firestore
- ARC
- SWIFT
- TDD
- RxSwift
- 리팩터링
- storekit2
- algorithm
- Di
- AutoLayout
- ios면접
- 카카오맵클론
- 앱의생명주기
- 코딩테스트입문
- five lines of code
- 프로그래머스
- Safari Inspector
- unittest
- firebase
- css학습
- Swift디자인패턴
- alamofire
- RC
- mrc
Archives
- Today
- Total
샘성의 iOS 개발 일지
[Tuist] 모듈 생성 자동화 하기 (tuist scaffold, .stencil) 본문
728x90
목적
원하는 모듈을 생성할 때마다 필요한 파일을 하나하나 세팅해주는 번거로움 해결하기.
→ 모듈에 필요한 코드를 템플릿 파일에 미리 작성해두고 tuist scaffold 명령어를 실행하면 자동으로 해당되는 모듈에 대한 파일 및 코드가 작성 됨.
준비물
- Tuist 폴더 안에 Templates 폴더 생성
- Templates 폴더의 하위 폴더로 '원하는 모듈 이름' 폴더 생성하기
- '원하는 모듈 이름' 폴더 안에 '원하는모듈이름.swift' 파일 직접 생성하기
파일 구조
...
└── Tuist
└── Templates
└── Domain
└── Domain.swift # Domain 모듈에 대한 템플릿 전체 설정
└── Package.stencil # Domain 모듈에 대한 패키지 템플릿 파일
└── Project.stencil # Domain 모듈에 대한 기본 프로젝트 템플릿 파일
└── InfoPlist.stencil # Domain 모듈에 대한 InfoPlist 템플릿 파일
└── Test.stencil # Domain 모듈의 테스트 파일에 대한 템플릿 파일

Domain.swift 파일
import ProjectDescription
// scaffold 명령어 시 받을 인자 정의
let name: Template.Attribute = .required("name") // 하위모듈명 (파일명)
let author: Template.Attribute = .required("author") // 생성자
let currentDate: Template.Attribute = .required("currentDate") // 생성 날짜
// 템플릿 선언
let domainTemplate = Template(
description: "A template for a new Domain modules",
attributes: [
name,
author,
currentDate
],
items: DomainTemplate.allCases.map { $0.item }
)
enum DomainTemplate: CaseIterable {
case package
case project
case infoPlist
case test
// 템플릿 내부에 추가할 파일
var item: Template.Item {
switch self {
case .package:
return .file(path: .basePath + "/Package.swift",
templatePath: "Package.stencil")
case .project:
return .file(path: .basePath + "/Sources/Project.swift",
templatePath: "Project.stencil")
case .infoPlist:
return .file(path: .basePath + "/\(name)-Info.plist",
templatePath: "InfoPlist.stencil")
case .test:
return .file(path: .basePath + "/Tests/" + .testName + "/" + .testName + ".swift",
templatePath: "Test.stencil")
}
}
}
// 명령어 실행시 Domain 모듈 파일이 생성될 기본 경로.
extension String {
static var basePath: Self {
return "Modules/Domain/\(name)"
}
static var testName: Self {
return "\(name)Tests"
}
}
Package.stencil 파일
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "{{ name }}",
platforms: [
.iOS(.v17) // 타겟 버전
],
products: [
.library(
name: "{{ name }}",
targets: ["{{ name }}"])
],
dependencies: [
// 필요한 의존성 추가
],
targets: [
.target(
name: "{{ name }}",
dependencies: []
)
]
)
Project.stencil 파일
// 기본 빈 프로젝트 파일로 세팅
import Foundation
class {{ name }} { }
InfoPlist.stencil 파일
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string> // region 설정
<key>CFBundleExecutable</key>
<string>{{ name }}</string>
<key>CFBundleIdentifier</key>
<string>앱번들.{{ name }}</string> // 번들 식별자 정의
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>{{ name }}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string> // 패키지 타입 프레임워크로 세팅
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string> // 타겟 플랫폼 설정
</array>
<key>MinimumOSVersion</key>
<string>17.0</string> // 최소 타겟 버전
</dict>
</plist>
Test.stencil 파일
// Test 코드를 위한 파일 템플릿
import XCTest
@testable import {{ name }}
class {{ name }}Tests: XCTestCase {
func testExample() {
// Example test case
}
}
템플릿으로 Domain 모듈 만들기
tuist scaffold Domain --name DomainSample --author Sam --current-date 2024/06/18


- 참고로 Domain.swift 파일에서 'name', 'author', 'currentDate'를 필수 인자로 설정해두었기 때문에 셋 중 하나라도 빠지면 아래와 비슷한 오류가 발생하며 모듈 생성이 불가능하다.

App의 Project.swift 파일에 모듈 추가하기
1. 앱의 모듈 구성 및 의존성을 관리하는 Project.swift 파일에 새로 생성한 모듈 패키지 및 의존성을 추가한다.
// 앱의 Project.swift 파일
let project = Project(
name: "MyApp",
packages: [
.local(path: .relativeToRoot("Modules/Domain/DomainSample")) // 생성한 모듈 패키지 추가
],
targets: [
.target(
name: "MyApp",
destinations: .iOS,
product: .app,
bundleId: "io.tuist.myApp",
deploymentTargets: .iOS("17.0"),
infoPlist: .extendingDefault(with: infoPlist),
sources: ["App/Sources/**"],
resources: ["App/Resources/**"],
dependencies: [
.package(product: "DomainSample") // 앱에 모듈 의존성 추가
],
),
.target(
name: "MyAppTests",
destinations: .iOS,
product: .unitTests,
bundleId: "io.tuist.myAppTests",
infoPlist: .default,
sources: ["App/Tests/**"],
resources: [],
dependencies: [.target(name: "MyApp")]
),
]
)
2. tuist generate 명령어를 통해 프로젝트를 재구성한다.
tuist generate


728x90
'iOS > Swift' 카테고리의 다른 글
[인앱결제] StoreKit2로 마이그레이션 하기 (+ 유실 방지 로직) (0) | 2024.07.23 |
---|---|
[알고리즘] 이진 탐색 (Binary Search) (0) | 2023.07.12 |
Firebase Remote Config로 앱 제어하기 (0) | 2023.07.06 |
Swift의 프로그래밍 패러다임 (0) | 2023.06.03 |
순열(Permutation) (0) | 2023.05.17 |