A production-grade SwiftUI app foundation kit. Type-safe navigation, declarative design tokens, a retry-aware async networking client, and a tiny key–value persistence abstraction — pure Swift, zero third-party dependencies, and strict-concurrency clean under the Swift 6 language mode.
Every new app re-solves the same four problems: routing, theming, networking, and lightweight persistence. SwiftUIBlueprint ships small, composable answers with the boring parts done right — Sendable everywhere, error taxonomy that distinguishes transport/status/decode failures, and a headless core you can unit test on any platform Swift runs on.
| Module | What you get |
|---|---|
| Networking | Endpoint (declarative request builder) · HTTPClient protocol · URLSessionHTTPClient (async/await over URLSession) · RetryPolicy (exponential backoff, injectable) · APIError with retryability classification |
| Navigation | Router<Route> — headless, type-safe navigation stack state machine · RouterView turns it into a NavigationStack |
| Theming | ColorToken (light/dark hex pairs) · Palette, SpacingScale, RadiusScale, Theme · .theme(…) environment modifier, padding(_:_) scale helper |
| Persistence | KeyValueStore protocol · UserDefaultsStore · thread-safe InMemoryKeyValueStore · Codable helpers |
- Swift 6.0+ toolchain (Xcode 16+ on Apple platforms)
- Deployment targets: iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0
- Why iOS 16? Apple's App Store data (Feb 12 2026, developer site) shows iOS 26 at 66% and iOS 18 at 24% of all active devices — only ~10% remain older, nearly all of those on iOS 17+. Independent trackers (Apr 2026) put dropping iOS 16 itself at under 3% audience loss, so iOS ≥16 covers comfortably more than 95% of active devices.
dependencies: [
.package(url: "https://github.com/wiradifit/swiftui-blueprint", from: "1.0.0")
]import SwiftUIBlueprint
let client = URLSessionHTTPClient(
retry: .exponential(base: .milliseconds(250), factor: 2, cap: .seconds(8), maxAttempts: 3)
)
struct Todo: Codable, Sendable { let id: Int; let title: String }
let endpoint = Endpoint(baseURL: URL(string: "https://jsonplaceholder.typicode.com")!)
.path("todos").path("1")
let todo: Todo = try await client.fetch(endpoint)
do {
_ = try await client.fetch(endpoint)
} catch let error as APIError {
// error.isRetryable tells you whether another attempt is plausible;
// .transport / .unacceptableStatus(code:response:body:) / .decoding are
// distinct cases so UI can react precisely.
}enum AppRoute: Hashable, Sendable {
case profile(id: Int)
case settings
}
struct RootScreen: View {
var body: some View {
RouterView(Router<AppRoute>()) {
HomeScreen()
} destination: { route in
switch route {
case .profile(let id): ProfileScreen(id: id)
case .settings: SettingsScreen()
}
}
}
}
// From any child screen:
router.push(.profile(id: 7))
router.pop()
router.popToRoot()
router.replaceTop(with: .settings) // e.g. post-login redirectThe router is @MainActor, observable through Combine on Apple platforms, and
fully unit-testable anywhere (onChange hook) — see Tests/.
var theme = Theme.default
theme.palette.accent = ColorToken(hexString: "#5E5CE6", darkHexString: "#7D7AFF")!
WindowGroup { RootScreen() }
.theme(theme)
Text("Hello").foregroundStyle(Color(token: theme.palette.accent))
Text("Padded").padding(.all, \.md) // 12 pt from the spacing ladderlet store = UserDefaultsStore(suiteName: "com.example.settings")
try store.setValue(Settings(notificationsEnabled: true, displayName: "Ada"), forKey: "settings")
let restored: Settings? = try store.value(Settings.self, forKey: "settings")This repository is developed primarily on a Linux CI host, where:
- ✅
swift buildpasses with zero warnings under Swift 6 language mode (strict concurrency is the default there — no data-race warnings). - ✅ All 30 tests in 6 suites pass (
swift test, swift-testing), covering endpoint building, HTTP status/retry/decode paths via a mockURLProtocol, router semantics, token parsing, and store round-trips. ⚠️ The SwiftUI surface layer (RouterView,Color(token:),.theme(…)) is guarded by#if canImport(SwiftUI)and therefore compile-verified only on Apple platforms — this host cannot run simulators or UIKit/AppKit. The GitHub Actions matrix builds the package for iOS Simulator on macOS to typecheck that layer on every push. No simulator runtime testing has been performed.
Run everything locally:
swift build
swift test- Headless core, thin shell. Navigation state lives in
Router(Foundation-only). The SwiftUI glue is additive and platform-guarded, which is what makes the logic testable off-Apple. - Swift 6 strict concurrency. Every public type is
Sendableor actor-isolated. The two@unchecked Sendables (URLSessionHTTPClient,UserDefaultsStore) exist solely to bridge missing annotations in swift-corelibs-foundation; both underlying types are documented thread-safe. - Portable networking. Requests go through the completion-based
URLSession.dataTaskwrapped in continuations, so the same code runs on Darwin and Linux (FoundationNetworking). In-flight cancellation is not wired to the socket; backoff sleeps are cancellable via task cancellation.
MIT — see LICENSE.