Comprehensive guidelines for building iOS apps with strict MVVM architecture, Core Data integration, modern SwiftUI patterns, and Swift concurrency best practices.
Expert guidance for building modern iOS applications following strict MVVM architecture with Core Data, Swift Concurrency, and iOS 18.5+ patterns.
When building SwiftUI applications, you MUST follow these architectural patterns and best practices:
**Views:**
**ViewModels:**
**Services:**
**Models:**
**Always use `NSFetchedResultsController`:**
**Implementation pattern:**
```swift
class MyViewModel: NSObject, ObservableObject, NSFetchedResultsControllerDelegate {
@Published var items: [Item] = []
private let fetchedResultsController: NSFetchedResultsController<Item>
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
items = fetchedResultsController.fetchedObjects ?? []
}
}
```
**Main Thread (only for):**
**Background Thread (required for):**
**Concurrency pattern:**
```swift
func performHeavyOperation() async {
isLoading = true
do {
// Background work
let result = try await service.fetchData()
// UI update on main thread
await MainActor.run {
self.data = result
self.isLoading = false
}
} catch {
await MainActor.run {
self.errorMessage = error.localizedDescription
self.isLoading = false
}
}
}
```
```swift
private var isProcessing = false
func criticalOperation() async {
guard !isProcessing else { return }
isProcessing = true
defer { isProcessing = false }
// ... operation code ...
}
```
**Complete implementation steps:**
1. **Define destination enums in MainView:**
```swift
enum CreateGroupDestination: Hashable {
case createGroup(User)
}
```
2. **Configure NavigationStack in MainView:**
```swift
struct MainView: View {
@State private var navigationPath = NavigationPath()
var body: some View {
NavigationStack(path: $navigationPath) {
ContentView(navigationPath: $navigationPath)
.navigationDestination(for: CreateGroupDestination.self) { destination in
switch destination {
case .createGroup(let user):
CreateGroupView(user: user, navigationPath: $navigationPath)
}
}
}
}
}
```
3. **Pass navigationPath to child views:**
```swift
struct ContentView: View {
@Binding var navigationPath: NavigationPath
Button("Navigate") {
navigationPath.append(CreateGroupDestination.createGroup(user))
}
}
```
4. **Navigate back programmatically:**
```swift
navigationPath.removeLast()
```
**Navigation Rules:**
```
Base/
View/
Loading/
Services/
Protocols/ # Service protocols
Implementation/ # Concrete implementations
CoreDataService.swift
ViewModel/
User/
Group/
Entry/
View/
User/
Group/
Entry/
Base/ # Reusable components
```
1. **Define Model** (Core Data entity)
2. **Create Service Protocol** in `Services/Protocols/`
3. **Implement Service** in `Services/Implementation/`
4. **Build ViewModel** with `@MainActor`, `ObservableObject`, dependency injection
5. **Create View** with `@StateObject` for ViewModel
6. **Add Navigation** enum and destination in MainView
7. **Test** with proper threading and Core Data integration
```swift
// In MainView
enum Destination: Hashable {
case detail(Item)
}
NavigationStack(path: $navigationPath) {
ListView(navigationPath: $navigationPath)
.navigationDestination(for: Destination.self) { destination in
switch destination {
case .detail(let item):
DetailView(item: item, navigationPath: $navigationPath)
}
}
}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/swiftui-expense-tracker-mvvm-architecture/raw