Section 16/171 menit
15. Real Use Cases
15. Real Use Cases
Use Case 1: Fintech App dengan 30 Module dan Team 20 Developer
Sebuah fintech app dengan arsitektur modular ketat: Core (4 module), Shared (5 module), Feature (20 module), App (1 module). Sebelum Tuist, clean build CI butuh 28 menit.
Struktur workspace:
swift
FinanceApp/
├── Tuist/
│ ├── Config.swift
│ ├── Package.swift
│ └── ProjectDescriptionHelpers/
│ ├── Settings/
│ │ └── Settings+Layers.swift
│ ├── Target/
│ │ └── Target+Module.swift
│ └── Project/
│ └── Project+Module.swift
├── Workspace.swift
├── Projects/
│ ├── App/
│ │ └── Project.swift
│ ├── Core/
│ │ ├── NetworkKit/Project.swift
│ │ ├── AuthKit/Project.swift
│ │ ├── AnalyticsKit/Project.swift
│ │ └── PersistenceKit/Project.swift
│ ├── Shared/
│ │ ├── SharedUI/Project.swift
│ │ ├── SharedModels/Project.swift
│ │ ├── DesignSystem/Project.swift
│ │ └── TestHelpers/Project.swift
│ └── Features/
│ ├── FeatureDashboard/Project.swift
│ ├── FeatureTransfer/Project.swift
│ └── ... (17 feature modules)
├── TestPlans/
│ ├── UnitTests.xctestplan
│ └── AllTests.xctestplan
└── Makefile
Config.swift dengan Tuist Cloud:
swift
// Tuist/Config.swift
import ProjectDescription
let config = Config(
cloud: .cloud(
projectId: "financeapp/ios",
url: "https://tuist.financeapp.internal",
options: [.optional] // CI jalan meski cloud tidak available
),
compatibleXcodeVersions: .list(["16.2"]),
swiftVersion: "6.0"
)
Architecture enforcement di Project.swift:
swift
// Tuist/ProjectDescriptionHelpers/Architecture/LayerRules.swift
import ProjectDescription
public enum ModuleLayer: String, CaseIterable {
case core, shared, feature, app
}
// Compile-time-safe dependency declarations
public extension TargetDependency {
static func core(_ module: CoreModule) -> TargetDependency {
.project(
target: module.rawValue,
path: .relativeToManifest("../../Core/\(module.rawValue)")
)
}
static func shared(_ module: SharedModule) -> TargetDependency {
.project(
target: module.rawValue,
path: .relativeToManifest("../../Shared/\(module.rawValue)")
)
}
}
public enum CoreModule: String {
case networkKit = "NetworkKit"
case authKit = "AuthKit"
case analyticsKit = "AnalyticsKit"
case persistenceKit = "PersistenceKit"
}
public enum SharedModule: String {
case sharedUI = "SharedUI"
case sharedModels = "SharedModels"
case designSystem = "DesignSystem"
case testHelpers = "TestHelpers"
}
swift
// Projects/Features/FeatureTransfer/Project.swift
import ProjectDescription
import ProjectDescriptionHelpers
let project = Project.module(
name: "FeatureTransfer",
layer: .feature,
dependencies: [
.core(.networkKit), // type-safe — typo langsung error di manifest compile
.core(.authKit),
.shared(.sharedUI),
.shared(.sharedModels),
.external(name: "Stripe"),
],
hasExampleApp: true
)
Hasil setelah implementasi Tuist:
- Clean build CI: 28 menit → 6 menit (cache hit Core + Shared = 22 menit saved)
- Onboarding developer baru: setup dari nol sampai bisa build = 15 menit (
make setup) - Implicit import violations ditemukan: 12 (semua diperbaiki saat migrasi)
- Circular dependency potential terdeteksi: 2 (sebelumnya tidak ketahuan)
Use Case 2: Rapid Development dengan Feature Example Apps
Tim membutuhkan cara untuk mengerjakan feature module secara isolated tanpa harus compile seluruh workspace:
swift
// Tuist/ProjectDescriptionHelpers/Target+ExampleApp.swift
import ProjectDescription
public extension Project {
static func moduleWithExample(
name: String,
layer: FeatureLayer,
dependencies: [TargetDependency] = [],
exampleDependencies: [TargetDependency] = []
) -> Project {
var targets = Target.make(name: name, layer: layer, dependencies: dependencies)
// Example app untuk isolated development
let exampleSources: [SourceFileGlob] = [
.glob("Example/Sources/**"),
]
// Check jika Example/ folder ada
let exampleTarget = Target.target(
name: "\(name)Example",
destinations: .iOS,
product: .app,
bundleId: "com.company.\(name.lowercased()).example",
deploymentTargets: .iOS("17.0"),
infoPlist: .extendingDefault(with: [
"UILaunchScreen": .dictionary([:]),
]),
sources: SourceFilesList(globs: exampleSources),
resources: "Example/Resources/**",
dependencies: [
.target(name: name),
.project(target: "TestHelpers", path: "../../Shared/TestHelpers"),
] + exampleDependencies,
settings: .settings(
base: [
"PRODUCT_BUNDLE_IDENTIFIER": "com.company.\(name.lowercased()).example",
]
)
)
targets.append(exampleTarget)
return Project(
name: name,
targets: targets,
schemes: [
// Scheme untuk open isolated example app
.scheme(
name: "\(name)-Example",
buildAction: .buildAction(targets: [
.target("\(name)Example")
]),
runAction: .runAction(
executable: .target("\(name)Example")
)
),
]
)
}
}
Developer workflow dengan example app:
swift
# Buka hanya FeatureCheckout dalam isolation
cd Projects/Features/FeatureCheckout
# Generate mini-workspace hanya untuk module ini
tuist generate
# Xcode buka dengan project berisi:
# - FeatureCheckout (framework)
# - FeatureCheckoutTests (unit tests)
# - FeatureCheckoutExample (standalone app)
# Pre-built: NetworkKit, SharedUI, dll (dari cache)
# Full compile time: ~30 detik (vs 8+ menit untuk seluruh workspace)