Skip to content

Repository files navigation

SwiftUI Starter Kit

A reference architecture for SwiftUI applications, not a template with the serial numbers filed off. Clone it, rename it, delete the sample feature, and you have a production-shaped app on day one.

  • Swift 6 language mode, strict concurrency complete
  • iOS 17+, SwiftUI, SwiftData, Swift Testing
  • Zero third-party dependencies — everything is Apple frameworks behind your own protocols
  • Protocol-oriented boundaries and constructor injection throughout
  • Router-based navigation with deep links and push-notification routing
  • QA / Production environments driven by .xcconfig + schemes, not #if DEBUG
  • AI scaffolding skills for VS Code Copilot in .github/prompts

Quick start

git clone <your-fork> SwiftUIStarterKit
cd SwiftUIStarterKit
open SwiftUIStarterKit.xcodeproj

Pick a scheme and run:

Scheme Configuration Backend Bundle id
SwiftUIStarterKit-Dev Debug QA host, verbose logs …swiftuistarterkit.dev
SwiftUIStarterKit-QA QA QA host, optimised …swiftuistarterkit.qa
SwiftUIStarterKit-Prod Release Production host …swiftuistarterkit

All three install side by side, so a tester can hold QA and production at once.

The sample app talks to jsonplaceholder.typicode.com — a free, public, no-key API — so it runs the moment you clone it. Sign in with any email containing @ and a password of four or more characters; Debug and QA builds use an offline DemoAuthService.

Make it yours (15 minutes)

  1. RenamePRODUCT_BUNDLE_IDENTIFIER_BASE in Config/Base.xcconfig.
  2. Point at your APIAPI_BASE_SCHEME / API_BASE_HOST / API_BASE_PATH in Config/QA.xcconfig and Config/Prod.xcconfig.
  3. Real authentication — in Core/DI/AppDependencies.swift, replace the DemoAuthService branch with RemoteAuthService, then delete DemoAuthService and adjust Network/DTOs/AuthDTO.swift to your payloads.
  4. Delete the sample feature — remove Features/TaskList, Features/TaskDetail, Data/Models/TaskItem.swift, Data/Repositories/TaskRepository.swift, Network/Endpoints/TaskEndpoints.swift and their AppRoute / FeatureFactory cases. If anything else breaks, the coupling was wrong and worth fixing.
  5. Brand it — colours and spacing live in DesignSystem/Theme/DesignTokens.swift; the accent colour is in Resources/Assets.xcassets/AccentColor.colorset.
  6. Push notifications — uncomment CODE_SIGN_ENTITLEMENTS in Config/Base.xcconfig, set DEVELOPMENT_TEAM, and enable the Push Notifications capability. Left off by default so a plain clone builds with no signing setup.

Architecture at a glance

                       ┌────────────────────────┐
                       │ SwiftUIStarterKitApp    │  @main
                       └──────────┬─────────────┘
                                  │ builds once
                       ┌──────────▼─────────────┐
                       │ AppDependencies         │  the composition root:
                       │  (the ONLY file that    │  the one place concrete
                       │   names concrete types) │  types are chosen
                       └──────────┬─────────────┘
              ┌───────────────────┼────────────────────┐
              │                   │                    │
     ┌────────▼────────┐ ┌────────▼────────┐ ┌─────────▼────────┐
     │ AppRouter        │ │ FeatureFactory  │ │ RootView          │
     │ (routes as data) │ │ (route → view)  │ │ (auth state → UI) │
     └──────────────────┘ └────────┬────────┘ └───────────────────┘
                                   │ injects protocols
     ┌─────────────────────────────▼──────────────────────────────┐
     │  Feature   View  ──►  ViewModel  ──►  RepositoryProtocol    │
     └──────────────────────────────────┬─────────────────────────┘
                        ┌───────────────┴───────────────┐
             ┌──────────▼─────────┐          ┌──────────▼─────────┐
             │ NetworkClientProtocol│        │ TaskLocalStore      │
             │  → NetworkClient     │        │  → SwiftDataTaskStore│
             └──────────┬─────────┘          └────────────────────┘
                        │ interceptors
             ┌──────────▼─────────┐
             │ TokenProviderProtocol│ ◄── AuthManager, Keychain, biometrics
             └────────────────────┘

Every arrow points at an abstraction. A feature never names a concrete service, which is what makes each piece replaceable, mockable and independently testable.

SwiftUIStarterKit/
├── App/            entry point, AppDelegate, RootView
├── Core/
│   ├── Configuration/  AppEnvironment, AppConfiguration
│   ├── DI/             AppDependencies, FeatureFactory, preview graph
│   ├── Navigation/     AppRoute, AppRouter
│   ├── Logging/        LoggerProtocol, OSLogLogger, redaction
│   ├── Analytics/      protocol, composite, vendor adapters
│   └── Extensions/     ViewState, UserFacingError, view helpers
├── Network/        APIEndpoint, NetworkClient, interceptors, DTOs
├── Data/           SwiftData models, LocalStore protocols, repositories
├── Security/       Auth, Biometrics, SecureStorage
├── Notifications/  permission, payloads, deep-link routing
├── DesignSystem/   tokens and shared components
└── Features/       one folder per screen: View + ViewModel

Documentation

Doc What it covers
01 Architecture Layers, dependency rule, why MVVM here
02 Dependency Injection The composition root, and why not a service locator
03 Networking Endpoints, client, interceptors, error mapping
04 Navigation Routes as data, the router, deep links
05 Security Keychain, tokens, refresh, biometrics
06 Push Notifications Permission, tokens, routing a tap
07 Analytics and Logging Event catalogue, adapters, redaction
08 Design System Tokens, components, accessibility
09 Testing What to test, the mock library, patterns
10 Environments and Schemes xcconfig → Info.plist → AppConfiguration
11 Adding a Feature Step-by-step walkthrough
12 Modularization When and how to split into SPM packages
AI Engineering Prompt The reusable prompt for building on this kit

AI tooling

.github/ ships Copilot instructions and reusable prompt files. In VS Code, open Copilot Chat and run:

  • /add-new-screen — asks for the screen name, feature folder and how it is reached, then generates view, view model, route, factory case and tests
  • /api-integration-scaffold — asks for paths, verbs and sample JSON, then generates DTOs, endpoints, repository, DI wiring and tests
  • /add-feature-module — a whole feature folder
  • /write-unit-tests — Swift Testing suites using the kit's mocks

.vscode/settings.json already enables prompt files, instruction files and chat modes. .github/copilot-instructions.md applies to every request; the files in .github/instructions/ apply to matching paths.

Testing

xcodebuild test \
  -project SwiftUIStarterKit.xcodeproj \
  -scheme SwiftUIStarterKit-Dev \
  -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest'

The suite runs with no network, no Keychain entitlement and no on-disk database. That is a property of the architecture, not of the tests.

License

MIT — see LICENSE.

About

Production-shaped SwiftUI starter kit — Swift 6, iOS 17+, zero dependencies. Protocol-oriented DI, router-based navigation, networking, SwiftData, Keychain auth, biometrics, push, analytics, design system, full test suite, and Copilot prompts for scaffolding screens and APIs.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages