A template project for building iOS/macOS apps with SwiftUI and Apple's Observation framework, featuring a modular package structure for better maintainability and scalability.
- 📦 Local Swift Package with modular architecture
- 👀 Observation-based state management
- 🎯 iOS 26 & macOS 26 support
- ✅ Includes test target setup
- 📱 Ready-to-use app structure
- 🗃️ SwiftData (official APIs only):
ModelContainer,@Query,modelContext
The template uses a modular architecture with clear separation of concerns:
graph LR
subgraph Local[Local Package]
Models --> DependencyClients
DependencyClients --> DependencyClientsLive
Models --> Features
DependencyClients --> Features
Features --> Views
Features --> PublicApp
Views --> PublicApp
DependencyClientsLive --> PublicApp
end
PublicApp --> XcodeApp[Xcode App Target]
Test targets are separate from runtime modules:
graph LR
subgraph Runtime
Models[Models]
Features[Features]
Views[Views]
end
subgraph Tests
ModelsTests[ModelsTests]
FeaturesTests[FeaturesTests]
ViewsTests[ViewsTests]
end
subgraph Deps
CustomDump[CustomDump]
end
Models --> ModelsTests --- CustomDump
Features --> FeaturesTests --- CustomDump
Views --> ViewsTests --- CustomDump
Models: Core data models and business logicFeatures: Observation-backed application modelsViews: SwiftUI views and UI componentsDependencyClients: Dependency client interfaces (native DI)DependencyClientsLive: Live implementations of dependency clientsPublicApp: Main app module that ties everything together
- Clone this template repository
- Update
appNameinPackage.swift - Run
swift package resolveto fetch dependencies - Build and run the project
- Create an iOS project in Xcode and import the package. The app target only needs an empty Swift file.
- Develop your app with code organized as modules in the package.
- When adding a new feature, create a new
@Observablemodel inFeatures. You can TDD it by adding tests in theFeaturesTestsmodule. You can build and testFeaturesscheme without building the whole app. - When developing a new view, create a new SwiftUI view in the
Viewsmodule. Leverage SwiftUI previews onViewsto iterate on the view without building the whole app.
This template uses SwiftData directly (no persistence wrapper layer):
PublicAppcreates a singleModelContainerand injects it using.modelContainer(...).Viewsread data via@Queryand write via@Environment(\.modelContext).
- swift-custom-dump (tests)
- iOS 26.0+ / macOS 26.0+
- Xcode 16.0+
- Swift 6.2+