Swift Architecture Audit
Instructions
Step 1: Explore the Project Structure
Identify the UI framework in use (SwiftUI, UIKit, or Mixed) by scanning the project — look for @main, UIApplicationDelegate, or UIHostingController. Then load the matching structure reference from ../swift-project-setup/references/ and use it as the baseline when identifying structural deviations.
Use subagents to parallelize exploration of large codebases.
Scan for:
- All feature folders and their naming patterns
- Number of
UIViewControllersubclasses vsViewModeltypes - Number of SwiftUI
Viewtypes - Presence of protocol files in
Core/orProtocols/ - Existing test targets and approximate test count
Step 2: MVVM Compliance Check
Read representative files from 3-5 key features. Look for:
Red flags (report each with file:line):
- Business logic, network calls, or storage access directly inside SwiftUI
Viewbodies - Business logic inside
UIViewControllersubclasses URLSession.sharedorUserDefaults.standardcalled from Views or ViewControllers- Missing ViewModel for any screen with non-trivial state
@Stateor@StateObjectholding data that belongs in a ViewModel or service
Green flags (note these):
ObservableObjector@ObservableViewModels with clear state- Services and repositories injected via initializer or
@Environment - Thin View layer (only layout and presentation)
- Coordinator / navigation layer separate from ViewModels
Step 3: Testability Assessment
For each audited type, check:
- Are dependencies hardcoded (
let service = NetworkService()) instead of injected? - Do networking/storage types hide behind protocols?
- Are global singletons used without injection support?
- Is there any existing test coverage? How much?
- Are ViewModels testable in isolation (no UIKit/SwiftUI imports)?
Scoring:
- High testability: Protocols + DI everywhere, existing tests
- Medium testability: Some DI, some singletons, few tests
- Low testability: No protocols, no DI, no tests — refactoring needed before testing is possible
Step 4: Concurrency Review
Identify:
- Completion handler usage where
async/awaitshould be used (new code) DispatchQueue.main.asyncscattered in ViewModel or service layers (use@MainActor)@Publishedproperties updated from background threads without actor isolation- Non-
Sendabletypes crossing actor boundaries (potential data races) sleep()anywhere in the codebase
Step 5: Anti-Pattern Inventory
| Anti-Pattern | Impact | Action |
|---|---|---|
| Massive ViewController | Untestable, unmaintainable | Extract ViewModel + Services |
| No protocol for external deps | Can't mock in tests | Wrap in protocol |
| Singleton abuse | Hidden coupling | Inject via init |
| Completion handlers in new code | Fragile async | Migrate to async/await |
| Force unwrap in production | Crashes | Replace with guard/if let |
| Business logic in View | Untestable | Move to ViewModel |
Step 6: Generate Audit Report
# Architecture Audit: [ProjectName]
Date: [date]
## Health Summary
Overall: [Good / Needs Work / Critical Issues]
MVVM Compliance: [High / Medium / Low]
Testability: [High / Medium / Low]
Concurrency: [Modern / Mixed / Legacy]
## Critical Issues (Fix First)
- [issue] in `FileName.swift:line` — [impact and suggested fix]
## Architectural Violations
- [violation] — [file(s) affected] — [recommended refactoring]
## Testability Blockers
- [blocker] — [which types are affected] — [fix: add protocol / inject dependency]
## Concurrency Issues
- [issue] — [file:line] — [suggested migration]
## Refactoring Priority
1. [Most critical — blocks testing or causes crashes]
2. [High priority — causes maintainability issues]
3. [Medium priority — worth cleaning up]
4. [Low priority / nice to have]
## Strengths
- [what the codebase does well — acknowledge good patterns]
Examples
Example 1: Legacy UIKit project
User says: "Audit the architecture, I want to add tests but everything is hard to test"
Actions:
- Explore folder structure with subagent
- Read 3 ViewControllers — assess logic placement
- Check for protocol/DI usage across service layer
- Generate prioritized audit report with specific files and lines
Example 2: SwiftUI project onboarding
User says: "I just joined this project, give me an architecture overview"
Actions:
- Map all feature modules
- Identify patterns: which architecture style is in use (MVVM, MV, etc.)
- Note testing state
- Generate onboarding summary + list of known issues
References
../swift-project-setup/references/structure-swiftui.md— expected SwiftUI layout../swift-project-setup/references/structure-uikit.md— expected UIKit layout../swift-project-setup/references/structure-mixed.md— expected Mixed layout../swift-project-setup/references/file-naming.md— naming rules and "What Never Goes Where" table
Troubleshooting
Codebase is too large to read fully: Use subagents to parallelize exploration. Focus the audit on the 3-5 most critical or highest-risk features (main flows, payment, authentication). Note coverage limitations in the report.
No clear architecture pattern found: Document what exists honestly. Don't assume intent. Recommend a migration path to MVVM with concrete first steps.