Agent skill
architecture-patterns
Choose and implement iOS architecture patterns (MVVM, TCA, Clean Architecture) based on feature complexity. Use when designing architecture for new features or refactoring existing code.
Install this agent skill to your Project
npx add-skill https://github.com/dagba/ios-mcp/tree/main/skills/architecture-patterns
SKILL.md
Architecture Patterns
Overview
Quick reference for choosing and implementing iOS architecture patterns. Focused on decision criteria, not tutorials.
Pattern Selection
| Complexity | Pattern | Use When |
|---|---|---|
| Simple | MV | Single screen, local state only |
| Medium | MVVM | 2-5 screens, business logic, network calls |
| Complex | TCA | State machines, side effects, complex flows |
| Enterprise | Clean | Multiple teams, maximum modularity |
Decision Tree
1. Single screen + local state only?
→ MV (SwiftUI View + @State)
2. Business logic or shared state?
→ MVVM
3. Complex state transitions?
→ TCA
4. Multi-team, high modularity?
→ Clean Architecture
MVVM Pattern (Most Common)
Structure:
- ViewModels:
@Observable, protocol-based DI - Views:
@State private var viewModel - Services: Protocols for testability
Critical Rules:
- ✅ Protocol-based DI via init (enables mocking)
- ✅
@MainActorfor state updates - ✅ Keep Views dumb (delegate to ViewModel)
- ❌ Never import SwiftUI in ViewModels
- ❌ Never use
@Published(use@Observable) - ❌ Never make ViewModels optional
Minimal Example:
protocol AuthServiceProtocol {
func login(_ email: String, _ password: String) async throws -> User
}
@Observable
final class LoginViewModel {
private let authService: AuthServiceProtocol
var email = ""
var password = ""
var isLoading = false
init(authService: AuthServiceProtocol = AuthService()) {
self.authService = authService
}
@MainActor
func login() async {
isLoading = true
defer { isLoading = false }
try? await authService.login(email, password)
}
}
struct LoginView: View {
@State private var viewModel = LoginViewModel()
var body: some View {
Form {
TextField("Email", text: $viewModel.email)
SecureField("Password", text: $viewModel.password)
Button("Login") { Task { await viewModel.login() } }
.disabled(viewModel.isLoading)
}
}
}
TCA Pattern
Use for: Complex state machines, side effects, time-travel debugging
Key: Single Reducer with State/Action/Dependencies. Exhaustive testing via TestStore.
Reference: TCA documentation
Clean Architecture
Use for: Enterprise apps, multiple teams, maximum testability
Patterns:
- VIP (View-Interactor-Presenter): Use
vip-clean-architectureskill for unidirectional data flow, protocol-based boundaries, and Spy-pattern testing - Generic Clean: Domain (entities, use cases) → Data (repositories, network) → Presentation (ViewModels, Views)
Key: Dependency inversion, protocol-based boundaries between layers
References
For detailed implementation examples and migration guides, see:
references/mvvm-patterns.mdreferences/tca-guide.mdreferences/clean-architecture.md
Word count: ~300 (was 2,863) For: Senior/mid iOS engineers who know how to code Focus: Decision-making, not hand-holding
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
gh-issue-fix-flow
End-to-end GitHub issue fix workflow using gh, local code changes, builds/tests, and git push. Use when asked to take an issue number, inspect the issue via gh, implement a fix, run XcodeBuildMCP builds/tests, commit with a closing message, and push.
realm-persistence
Use when implementing Realm database in iOS apps, encountering thread-safety errors, async/await crashes, performance issues with sync/writes, or integrating with Codable APIs
viper-architecture-rambler
Use when architecting complex iOS apps with multiple features, long-term maintenance requirements, or team scalability needs. Use when refactoring Massive View Controllers or implementing testable architecture. Do NOT use for simple single-screen apps, rapid prototypes, or small utility tools.
swiftui-ui-patterns
Best practices and example-driven guidance for building SwiftUI views and components. Use when creating or refactoring SwiftUI UI, designing tab architecture with TabView, composing screens, or needing component-specific patterns and examples.
swiftui-liquid-glass
Implement, review, or improve SwiftUI features using the iOS 26+ Liquid Glass API. Use when asked to adopt Liquid Glass in new SwiftUI UI, refactor an existing feature to Liquid Glass, or review Liquid Glass usage for correctness, performance, and design alignment.
swiftui-view-refactor
Refactor and review SwiftUI view files for consistent structure, dependency injection, and Observation usage. Use when asked to clean up a SwiftUI view’s layout/ordering, handle view models safely (non-optional when possible), or standardize how dependencies and @Observable state are initialized and passed.
Didn't find tool you were looking for?