Section 17/181 menit
17. Real Use Cases
17. Real Use Cases
Use Case 1: Setup Project Baru yang Production-Ready dari Hari Pertama
Script bootstrap yang mengotomasi setup lengkap untuk project baru.
swift
#!/bin/bash
# setup-ios-project.sh
set -e
PROJECT_NAME="${1:-MyApp}"
BUNDLE_ID="${2:-com.mycompany.myapp}"
TEAM_ID="${3:-ABCDEF1234}"
echo "🚀 Setting up $PROJECT_NAME..."
# Install dependencies
brew install swiftlint swiftformat periphery pre-commit fastlane
# Init Xcode project (jika belum ada)
if [ ! -f "$PROJECT_NAME.xcodeproj/project.pbxproj" ]; then
echo "Create project di Xcode dulu, lalu jalankan script ini."
exit 1
fi
# Setup xcconfig
mkdir -p Configurations
cat > Configurations/Base.xcconfig << EOF
PRODUCT_BUNDLE_IDENTIFIER = $BUNDLE_ID
DEVELOPMENT_TEAM = $TEAM_ID
SWIFT_VERSION = 5.0
IPHONEOS_DEPLOYMENT_TARGET = 17.0
EOF
cat > Configurations/Debug.xcconfig << EOF
#include "Base.xcconfig"
SWIFT_OPTIMIZATION_LEVEL = -Onone
ENABLE_TESTABILITY = YES
GCC_PREPROCESSOR_DEFINITIONS = \$(inherited) DEBUG=1
BASE_URL = https://api-dev.myapp.com
EOF
cat > Configurations/Release.xcconfig << EOF
#include "Base.xcconfig"
SWIFT_OPTIMIZATION_LEVEL = -O
SWIFT_COMPILATION_MODE = wholemodule
STRIP_INSTALLED_PRODUCT = YES
BASE_URL = https://api.myapp.com
EOF
# Setup SwiftLint
cat > .swiftlint.yml << 'EOF'
opt_in_rules:
- force_unwrapping
- empty_string
- first_where
- sorted_first_last
disabled_rules:
- trailing_whitespace
line_length:
warning: 120
error: 200
ignores_comments: true
excluded:
- Pods
- .build
- Packages
EOF
# Setup SwiftFormat
cat > .swiftformat << 'EOF'
--indent 4
--allman false
--wraparguments before-first
--maxwidth 120
--self init-only
--commas always
--semicolons never
--emptybraces no-space
--linebreaks lf
--enable isEmpty
--enable sortedImports
--enable unusedArguments
--exclude Pods,.build,Packages
EOF
# Setup Makefile
cat > Makefile << 'MAKEOF'
.PHONY: setup lint format test clean ci
setup:
brew install swiftlint swiftformat pre-commit
pre-commit install
lint:
swiftlint --strict
format:
swiftformat .
lint-ci:
swiftlint --strict && swiftformat . --lint
test:
xcodebuild test \
-project *.xcodeproj \
-scheme $(shell ls *.xcodeproj | head -1 | sed 's/.xcodeproj//') \
-destination "platform=iOS Simulator,name=iPhone 15 Pro" \
-quiet
clean:
rm -rf build/ DerivedData/
ci: lint-ci test
@echo "✓ CI passed"
MAKEOF
# Setup pre-commit
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: local
hooks:
- id: swiftlint
name: SwiftLint
entry: swiftlint
language: system
types: [swift]
- id: swiftformat
name: SwiftFormat
entry: swiftformat
args: [--lint]
language: system
types: [swift]
EOF
pre-commit install
# Setup Fastlane
fastlane init <<< "2" # Option 2: automate App Store distribution
# Setup Periphery
periphery setup
# Git ignore additions
cat >> .gitignore << 'EOF'
# Fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
fastlane/*.cer
fastlane/*.p12
# Build artifacts
build/
*.xcarchive
*.ipa
*.dSYM.zip
EOF
echo ""
echo "✅ $PROJECT_NAME setup complete!"
echo ""
echo "Next steps:"
echo " 1. Set xcconfig di Xcode Build Settings"
echo " 2. Configure Fastlane Match: fastlane match init"
echo " 3. Setup Xcode Cloud di Xcode → Product → Xcode Cloud"
echo " 4. Add BASE_URL ke Info.plist: BASE_URL = \$(BASE_URL)"
Use Case 2: CI Pipeline di GitHub Actions (Alternatif Xcode Cloud)
swift
# .github/workflows/ios-ci.yml
name: iOS CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
name: Code Quality
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- name: Install SwiftLint
run: brew install swiftlint swiftformat
- name: SwiftLint
run: swiftlint --strict
- name: SwiftFormat
run: swiftformat . --lint
test:
name: Unit Tests
runs-on: macos-15
needs: lint
steps:
- uses: actions/checkout@v4
- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_16.3.app
- name: Cache SPM
uses: actions/cache@v4
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
- name: Run Tests
run: |
xcodebuild test \
-project MyApp.xcodeproj \
-scheme MyApp \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.4" \
-resultBundlePath TestResults.xcresult \
| xcpretty --report junit --output test-results.xml
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: test-results.xml
build:
name: Build Archive
runs-on: macos-15
needs: test
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Install Fastlane
run: bundle install
- name: Import Certificates
env:
CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
CERTIFICATES_PASSWORD: ${{ secrets.CERTIFICATES_PASSWORD }}
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}
run: |
echo "$CERTIFICATES_P12" | base64 --decode > cert.p12
security import cert.p12 -P "$CERTIFICATES_PASSWORD" \
-k ~/Library/Keychains/login.keychain-db -T /usr/bin/codesign
- name: Build & Upload to TestFlight
env:
APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_API_KEY }}
run: bundle exec fastlane beta
- name: Upload dSYMs
run: ./Scripts/upload_dsyms.sh build/MyApp.xcarchive
Use Case 3: Otomasi Deteksi Performa Regression
Script yang dijalankan nightly untuk mendeteksi penurunan performa build.
swift
#!/bin/bash
# scripts/check_build_performance.sh
set -e
PROJECT="MyApp.xcodeproj"
SCHEME="MyApp"
THRESHOLD_SECONDS=180 # Alert jika build > 3 menit
LOG_FILE="/tmp/build_timing.log"
echo "Building $SCHEME..."
START=$(date +%s)
xcodebuild build \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Debug \
-destination "platform=iOS Simulator,name=iPhone 15 Pro" \
-derivedDataPath /tmp/BuildTimingDerivedData \
clean build \
2>&1 | tee "$LOG_FILE" | grep -E "error:|warning:|Build complete"
END=$(date +%s)
DURATION=$((END - START))
echo "Build time: ${DURATION}s"
# Simpan ke history
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $DURATION" >> build_times.log
# Alert jika melebihi threshold
if [ $DURATION -gt $THRESHOLD_SECONDS ]; then
# Cari fungsi dengan compile time paling lama
grep "expression took" "$LOG_FILE" | sort -t= -k2 -rn | head -10
echo "⚠️ Build time ${DURATION}s melebihi threshold ${THRESHOLD_SECONDS}s!"
# Kirim notifikasi (Slack, email, dll)
if [ -n "$SLACK_WEBHOOK" ]; then
curl -X POST "$SLACK_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"text\": \"⚠️ Build time regression: ${DURATION}s (threshold: ${THRESHOLD_SECONDS}s)\"}"
fi
exit 1
fi
echo "✓ Build time ${DURATION}s OK (threshold: ${THRESHOLD_SECONDS}s)"