Section 12/131 menit
12. Real Use Cases
12. Real Use Cases
Use Case 1: Startup Menghilangkan Merge Conflict dengan XcodeGen
Tim iOS 6 developer di fintech startup mengalami merge conflict .xcodeproj setiap sprint. Setiap feature branch yang menyentuh folder berbeda menghasilkan conflict UUID yang harus di-resolve manual.
Setup XcodeGen:
swift
# project.yml — konfigurasi lengkap untuk startup app
name: FinanceApp
options:
bundleIdPrefix: com.fintech
deploymentTarget:
iOS: "17.0"
defaultConfig: Debug
createIntermediateGroups: true # mirror folder structure di project navigator
xcodeVersion: "16.2"
transitivelyLinkDependencies: true
settings:
base:
SWIFT_VERSION: 6.0
SWIFT_STRICT_CONCURRENCY: complete
ENABLE_BITCODE: NO
DEBUG_INFORMATION_FORMAT: dwarf-with-dsym
configs:
Debug:
OTHER_SWIFT_FLAGS: "$(inherited) -DDEBUG"
SWIFT_OPTIMIZATION_LEVEL: "-Onone"
Staging:
OTHER_SWIFT_FLAGS: "$(inherited) -DSTAGING"
SWIFT_OPTIMIZATION_LEVEL: "-O"
VALIDATE_PRODUCT: YES
Release:
SWIFT_OPTIMIZATION_LEVEL: "-O"
VALIDATE_PRODUCT: YES
targets:
FinanceApp:
type: application
platform: iOS
sources:
- path: Sources/App
excludes:
- "**/__Snapshots__"
resources:
- Sources/App/Assets.xcassets
- Sources/App/Localizable.strings
dependencies:
- target: NetworkKit
- target: AuthKit
- target: FeatureDashboard
- target: FeatureTransaction
- package: FirebaseAnalytics
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.app
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
configs:
Debug:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.app.debug
Staging:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.app.staging
NetworkKit:
type: framework
platform: iOS
sources: Modules/NetworkKit/Sources
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.networkkit
AuthKit:
type: framework
platform: iOS
sources: Modules/AuthKit/Sources
dependencies:
- target: NetworkKit
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.authkit
FeatureDashboard:
type: framework
platform: iOS
sources: Modules/FeatureDashboard/Sources
dependencies:
- target: NetworkKit
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.featuredashboard
FeatureTransaction:
type: framework
platform: iOS
sources: Modules/FeatureTransaction/Sources
dependencies:
- target: NetworkKit
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.fintech.featuretransaction
FinanceAppTests:
type: bundle.unit-test
platform: iOS
sources: Tests/FinanceAppTests
dependencies:
- target: FinanceApp
packages:
Firebase:
url: https://github.com/firebase/firebase-ios-sdk
from: "11.0.0"
FirebaseAnalytics:
package: Firebase
product: FirebaseAnalytics
Makefile untuk workflow:
swift
# Makefile — shortcut untuk developer
.PHONY: generate clean bootstrap
generate:
xcodegen generate
clean:
rm -rf FinanceApp.xcodeproj FinanceApp.xcworkspace
bootstrap: generate
@echo "Project generated. Open FinanceApp.xcodeproj"
# Git hook setup
setup-hooks:
cp scripts/post-checkout .git/hooks/post-checkout
chmod +x .git/hooks/post-checkout
@echo "Git hooks installed"
Use Case 2: Scale-Up ke Tuist dengan Binary Caching
Perusahaan e-commerce dengan 15 iOS developer dan 20+ module membutuhkan solusi untuk build time yang sudah 25 menit di CI.
Workspace.swift:
swift
// Workspace.swift
import ProjectDescription
let workspace = Workspace(
name: "ShopApp",
projects: [
"Projects/App",
"Projects/Core/NetworkKit",
"Projects/Core/AuthKit",
"Projects/Core/AnalyticsKit",
"Projects/Core/SharedUI",
"Projects/Features/FeatureHome",
"Projects/Features/FeatureSearch",
"Projects/Features/FeatureCart",
"Projects/Features/FeatureCheckout",
"Projects/Features/FeatureProfile",
"Projects/Features/FeatureOrders",
],
generationOptions: .options(
automaticSchemesOptions: .enabled(
targetSchemesGrouping: .byNameSuffix(
build: [],
test: ["Tests"],
run: ["App"]
)
)
)
)
Project.swift untuk FeatureCheckout:
swift
// Projects/Features/FeatureCheckout/Project.swift
import ProjectDescription
import ProjectDescriptionHelpers
let project = Project.feature(
name: "FeatureCheckout",
dependencies: [
.project(target: "NetworkKit", path: "../../Core/NetworkKit"),
.project(target: "AuthKit", path: "../../Core/AuthKit"),
.project(target: "SharedUI", path: "../../Core/SharedUI"),
.external(name: "Stripe"),
],
additionalResources: [
"Resources/Localizable.strings",
"Resources/PaymentAssets.xcassets",
]
)
CI script dengan Tuist cache:
swift
#!/bin/bash
# scripts/ci-build.sh — digunakan di GitHub Actions
set -euo pipefail
echo "=== Setting up Tuist ==="
mise install
echo "=== Warming cache ==="
# Dalam CI: coba gunakan cache yang tersimpan
tuist cache --external-only 2>/dev/null || true
echo "=== Generating project ==="
tuist install
tuist generate
echo "=== Building ==="
xcodebuild build-for-testing \
-scheme ShopApp \
-destination "platform=iOS Simulator,name=iPhone 15" \
-derivedDataPath DerivedData \
| xcpretty
echo "=== Running tests ==="
xcodebuild test-without-building \
-scheme ShopApp \
-destination "platform=iOS Simulator,name=iPhone 15" \
-derivedDataPath DerivedData \
-resultBundlePath TestResults.xcresult \
| xcpretty
echo "=== Done ==="
Hasilnya: build time CI turun dari 25 menit menjadi 7 menit rata-rata karena modul Core (NetworkKit, AuthKit, SharedUI) tidak perlu dikompilasi ulang ketika hanya feature module yang berubah.