Welcome! This guide will help you navigate the NavigationSplitView examples and choose the right learning path.
-
Open the project:
open /path/to/SwiftUIExamples/SwiftUIExamples.xcodeproj
-
Run the app (Cmd+R in Xcode)
-
Try all four examples:
- Click "Views Only" - Simplest pattern
- Click "MVVM Pattern" - Production-ready pattern
- Click "MVVM-C Pattern" - Navigation separation pattern
- Click "VIPER Pattern" - Maximum separation
-
Explore the 3-pane layout:
- Select categories in the sidebar
- Browse items in the content list
- View details in the detail pane
- Try the Settings category
New to SwiftUI?
β Start with ViewOnly_Architecture.md
Familiar with SwiftUI basics?
β Jump to MVVM_Architecture.md
Need navigation separation?
β Check out MVVMC_Architecture.md
Want maximum separation?
β Check out VIPER_Architecture.md
Want the big picture?
β Read README.md first
Need implementation details?
β Check IMPLEMENTATION_SUMMARY.md
graph LR
A[README.md] --> B[ViewOnly_Architecture.md]
B --> C[Run ViewOnly Example]
C --> D[Read ViewOnly Code]
D --> E[MVVM_Architecture.md]
E --> F[Run MVVM Example]
F --> G[Compare Implementations]
style A fill:#e8f5e9
style B fill:#fff4e1
style C fill:#e1f5ff
style D fill:#fff4e1
style E fill:#f3e5f5
style F fill:#e1f5ff
style G fill:#fff4e1
Estimated Time: 2-3 hours
Steps:
-
Read
README.md(10 min)- Understand what both patterns offer
- See the high-level comparison
-
Read
ViewOnly_Architecture.md(30 min)- Learn SwiftUI state management basics
- Understand
@Stateand@Binding - Study the architecture diagrams
-
Run ViewOnly Example (15 min)
- Open in Xcode and run
- Interact with all features
- Try adding/editing items
-
Read ViewOnly Code (45 min)
- Start with
NavigationSplitViewViewOnlyContentView.swift - Follow the inline comments
- Understand data flow with
@Binding
- Start with
-
Read
MVVM_Architecture.md(45 min)- Learn separation of concerns
- Understand
@Observablemacro - Study ViewModel patterns
-
Run MVVM Example (15 min)
- See the same UI, different architecture
- Try all features
-
Compare Implementations (30 min)
- Open files side-by-side
- Compare state management approaches
- Read
DATA_FLOW_EXPLANATION.md
graph LR
A[README.md] --> B[MVVM_Architecture.md]
B --> C[Review @Observable]
C --> D[Study ViewModels]
D --> E[Compare with ViewOnly]
E --> F[Build Your Own]
style A fill:#e8f5e9
style B fill:#f3e5f5
style C fill:#e1f5ff
style D fill:#fff4e1
style E fill:#e1f5ff
style F fill:#a5d6a7
Estimated Time: 1-2 hours
Steps:
-
Skim
README.md(5 min)- Get project overview
-
Read
MVVM_Architecture.md(40 min)- Focus on
@Observablesection - Study the architecture diagrams
- Understand ViewModel responsibilities
- Focus on
-
Study
MVVMAppViewModel.swift(20 min)- See how central coordinator works
- Understand property observation
-
Compare
ContentListViewModelwith ViewOnly (20 min)- Open both implementations side-by-side
- See how business logic moves to ViewModel
- Compare state management
-
Read
DATA_FLOW_EXPLANATION.md(15 min)- Understand data flow differences
-
Build Your Own (flexible)
- Use MVVM example as template
- Apply pattern to your project
graph LR
A[IMPLEMENTATION_SUMMARY.md] --> B[MVVM ViewModels]
B --> C[Architecture Diagrams]
C --> D[Apply Patterns]
style A fill:#f3e5f5
style B fill:#e1f5ff
style C fill:#fff4e1
style D fill:#a5d6a7
Estimated Time: 30-45 minutes
Steps:
-
Read
IMPLEMENTATION_SUMMARY.md(15 min)- Get complete overview
- See architecture comparison
- Review key technologies
-
Study MVVM ViewModels (15 min)
MVVMAppViewModel.swift- Coordinator patternMVVMContentListViewModel.swift- CRUD operationsMVVMSidebarViewModel.swift- Navigation state
-
Review Architecture Diagrams (10 min)
- Mermaid diagrams in
MVVM_Architecture.md - Data flow visualizations
- Mermaid diagrams in
-
Apply to Your Project (flexible)
- Copy patterns that fit your needs
- Adapt ViewModels for your domain
graph LR
A[VIPER_Architecture.md] --> B[Understand 5 Components]
B --> C[Study Router]
C --> D[Study Interactors]
D --> E[Study Presenters]
E --> F[Compare with MVVM]
style A fill:#ffe0b2
style B fill:#fff4e1
style C fill:#e1f5ff
style D fill:#f3e5f5
style E fill:#e1f5ff
style F fill:#a5d6a7
Estimated Time: 2-3 hours
Steps:
-
Read
VIPER_Architecture.md(60 min)- Understand all 5 components (V-I-P-E-R)
- Study the architecture diagram
- Learn when to use VIPER vs. MVVM
-
Study the Router (20 min)
- Read
VIPERRouter.swift - See how it creates and wires modules
- Understand navigation state management
- Read
-
Study Interactors (30 min)
- Read
VIPERContentListInteractor.swift - See pure business logic separation
- Compare with ViewModel business logic
- Read
-
Study Presenters (30 min)
- Read
VIPERContentListPresenter.swift - See how it formats data from Interactor
- Understand delegation to Router
- Read
-
Run VIPER Example (15 min)
- Same UI as MVVM, different architecture
- Try all features
-
Compare VIPER with MVVM (30 min)
- Open files side-by-side
- See business logic separation (Interactor vs. ViewModel)
- Compare navigation (Router vs. ViewModel)
- Understand complexity trade-offs
Key Concepts:
@Statefor local view state@Bindingfor shared state between views- State lives in view hierarchy
- Simple and direct
Files to Study:
Examples/ViewOnly/
βββ NavigationSplitViewViewOnlyContentView.swift β Start here
βββ NavigationSplitViewViewOnlySidebarView.swift β See @Binding usage
βββ NavigationSplitViewViewOnlyContentListView.swift β Study state management
Key Concepts:
@Observablefor automatic state tracking- ViewModels contain business logic
- Views are thin UI layers
- Testable and maintainable
Files to Study:
Examples/MVVM/
βββ ViewModels/
β βββ MVVMAppViewModel.swift β Start here (coordinator)
β βββ MVVMContentListViewModel.swift β CRUD operations
β βββ MVVMSidebarViewModel.swift β Navigation state
βββ Views/
βββ MVVMContentView.swift β See how Views use ViewModels
Key Concepts:
- Five separate components (V-I-P-E-R)
- Maximum separation of concerns
- Router creates and wires modules
- Interactor has ONLY business logic
- Presenter has ONLY presentation logic
- Most testable but most complex
Files to Study:
Examples/VIPER/
βββ Router/
β βββ VIPERRouter.swift β Start here (module coordinator)
βββ Interactors/
β βββ VIPERContentListInteractor.swift β Business logic
β βββ VIPERSidebarInteractor.swift
βββ Presenters/
β βββ VIPERContentListPresenter.swift β Presentation logic
β βββ VIPERSidebarPresenter.swift
βββ Entities/
β βββ VIPERListItem.swift β Pure data models
β βββ VIPERSidebarCategory.swift
βββ Views/
βββ VIPERContentView.swift β Dumb views
// `@State` creates a source of truth owned by the view
@State private var items: [Item] = []
// SwiftUI automatically updates UI when this changes
items.append(newItem) // UI updates!When to use:
- View needs to own and manage data
- Data doesn't need to be shared with other views
- Simple state management
// `@Binding` creates a two-way connection to someone else's state
@Binding var selectedItem: Item?
// Changes flow both ways:
selectedItem = newItem // Parent sees change
// Parent changes also update this viewWhen to use:
- Sharing state between parent and child views
- Child needs to read AND write parent's data
- Simple data passing
// `@Observable` makes a class trackable by SwiftUI
@Observable
class AppViewModel {
var items: [Item] = []
var selectedItem: Item?
// All properties automatically tracked!
}
// In views:
@State private var viewModel = AppViewModel()
// SwiftUI updates view when ANY property changesWhen to use:
- Separating business logic from views
- Managing complex state
- Building testable code
- Production applications
Use ViewOnly if:
- Learning SwiftUI for the first time
- Building a small, simple app
- Prototyping quickly
- You don't need automated testing
Use MVVM if:
- Building a production application
- Working in a team
- Need unit testing
- App will grow over time
- Want clear separation of concerns
Use VIPER if:
- Building a large, complex application
- Large team (5+ developers)
- Maximum testability required
- Complex business logic
- Multiple modules/features
- Long-term maintenance (years)
Quick Decision Guide:
Simple app (< 10 screens)? β ViewOnly
Moderate app (10-50 screens)? β MVVM
Large app (50+ screens)? β VIPER
Learning SwiftUI? β ViewOnly
Production app with testing? β MVVM
Enterprise app with large team? β VIPER
Short answer: Not recommended within the same feature.
Better approach:
- Keep patterns separate by feature/module
- Choose one pattern for your project
- Use ViewOnly for learning, MVVM for production
| Aspect | @State | @Observable |
|---|---|---|
| Scope | Single view | Multiple views |
| Ownership | View owns data | ViewModel owns data |
| Logic Location | In view | In ViewModel |
| Testability | Hard to test | Easy to test |
| Best For | Simple UI state | Business logic |
No! The @Observable macro (iOS 17+) replaces the need for Combine in most cases.
Old way (Combine):
class ViewModel: ObservableObject {
@Published var items: [Item] = [] // Needs Combine
}New way (@Observable):
@Observable
class ViewModel {
var items: [Item] = [] // No Combine needed!
}Benefits:
-
Testability
- Test ViewModels without UI
- Mock data with Models
- Verify business logic independently
-
Maintainability
- Change UI without touching logic
- Update logic without breaking UI
- Clear responsibilities
-
Reusability
- Share ViewModels across platforms
- Reuse Models in different contexts
- Compose Views freely
-
Collaboration
- Team members work on different layers
- Less merge conflicts
- Clear ownership
Goal: Add a new category
Steps:
- Open
NavigationSplitViewViewOnlySidebarCategory.swift - Add a new case to the enum:
.shopping - Update the switch statement in
defaultContent - Run and see your new category!
Time: 15 minutes
Goal: Add a priority field to items
Steps:
- Update
MVVMListItem.swift- addpriority: Stringproperty - Update
MVVMContentListViewModel.swift- include priority in new items - Update
MVVMDetailView.swift- display priority - Update
MVVMInfoRow.swift- add priority field - Run and test!
Time: 30 minutes
Goal: Understand architectural differences
Steps:
-
Implement same feature in both patterns:
- Add "favorite" flag to items
- Filter to show only favorites
-
Compare:
- Where does state live?
- Where is logic implemented?
- How many files did you touch?
- Which was easier to test?
-
Write notes on differences
Time: 1-2 hours
- README.md - Project overview
- IMPLEMENTATION_SUMMARY.md - Complete reference
- ViewOnly_Architecture.md - Simple pattern
- MVVM_Architecture.md - Production pattern
- DATA_FLOW_EXPLANATION.md - Data flow details
Entry Points:
TestyApp.swift- App setupImplementationSelectionView.swift- Example selector
ViewOnly:
NavigationSplitViewViewOnlyContentView.swift- Main view
MVVM:
MVVMContentView.swift- Main viewMVVMAppViewModel.swift- Central coordinator
After completing your chosen learning path, you should be able to:
ViewOnly Pattern:
- Explain what
@Statedoes - Use
@Bindingto share state - Create a 3-pane NavigationSplitView
- Manage state within views
- Handle user input with property wrappers
MVVM Pattern:
- Explain what
@Observabledoes - Create ViewModels with business logic
- Separate concerns (Model/ViewModel/View)
- Use ViewModels from Views
- Design testable architecture
Both Patterns:
- Build NavigationSplitView layouts
- Support different content types
- Handle multi-window on macOS
- Understand data flow
- Make informed architecture decisions
- Read MVVM documentation
- Compare implementations side-by-side
- Build a small MVVM project
- Practice unit testing ViewModels
- Apply to your own project
- Explore advanced patterns:
- Repository pattern for data
- Dependency injection
- Coordinator pattern for navigation
- Build a complete app
- Apple's SwiftUI Tutorials: developer.apple.com/tutorials/swiftui
- Swift by Sundell: swiftbysundell.com
- Hacking with Swift: hackingwithswift.com
- WWDC Videos: Search "SwiftUI" on developer.apple.com
- Read inline code comments - Every file has detailed explanations
- Check architecture diagrams - Visual guides in documentation
- Compare patterns - See differences side-by-side
- Build and experiment - Change code and see what happens
Pitfall 1: Mixing @State and @Observable
// β Don't do this
@State var viewModel: MVVMAppViewModel // Wrong wrapper!
// β
Do this
@State private var viewModel = MVVMAppViewModel() // Correct!Pitfall 2: Forgetting @Observable
// β Without @Observable, views won't update
class ViewModel {
var items: [Item] = []
}
// β
With @Observable, automatic tracking
@Observable
class ViewModel {
var items: [Item] = []
}Pitfall 3: Putting Logic in Views (MVVM)
// β Logic in View
struct MyView: View {
func calculateTotal() -> Double { ... } // Wrong place!
}
// β
Logic in ViewModel
@Observable
class MyViewModel {
func calculateTotal() -> Double { ... } // Correct!
}| Task | Time |
|---|---|
| Quick Start | 5 minutes |
| Complete Beginner Path | 2-3 hours |
| SwiftUI Developer Path | 1-2 hours |
| Experienced Developer Path | 30-45 minutes |
| Exercise 1 (Easy) | 15 minutes |
| Exercise 2 (Medium) | 30 minutes |
| Exercise 3 (Advanced) | 1-2 hours |
Remember:
- Start simple - ViewOnly first if you're new
- Experiment - Change code and see what happens
- Read comments - Every file has explanations
- Build things - Best way to learn
- Compare patterns - See differences yourself
Happy coding! π
Last Updated: 2025
Swift Version: 5.9+
Minimum iOS: 17.0
Minimum macOS: 14.0