TheSwiftKit – SwiftUI App Template Documentation
Overview
TheSwiftKit is a production‑ready SwiftUI template with modular features: onboarding, authentication, paywall/subscriptions, analytics, notifications, AI wrappers, settings, and local persistence.
Goal: clone → paste keys → set app name/colors → run. No code rewrites required for the typical setup.
Requirements
- Xcode 15+ and Swift 5.9+
- iOS 16+ target
- Accounts as needed: Supabase (Auth, Database, Storage), RevenueCat (IAP/Subscriptions), TelemetryDeck (Analytics), OpenAI (optional, for AI backend)
- Optional tools: Supabase CLI (for Edge Functions), Python 3.10+ (for local AI server)
Quick Start
- Clone the repo and open
TheSwiftKit.xcodeproj
. - Duplicate
Config/Secrets.sample.swift
toConfig/Secrets.swift
and fill your keys. - Set your app name and branding:
- App name:
Config/AppConfig.swift
- Theme colors:
Core/Theme/DesignTokens.swift
- Bundle ID:
project.yml
(or Xcode’s Signing settings) - App icons:
Resources/Assets.xcassets/AppIcon.appiconset
. Optional logo: addAppLogo
image in Assets.
- App name:
- Build and run. If keys are missing, the app falls back to safe no‑op services.
Configuration
App config (Config/AppConfig.swift
)
appName
: Set the display name for UI. The app replaces “APP_NAME” tokens in localized strings automatically.bundleId
: Informational field; the actual bundle identifier is set in project settings.backend
:.supabase
or.local
. Controls which repository implementations DI selects.layout
:.list
or.grid
for HomeView model (example).onboardingStyle
:.carousel
,.highlights
, or.minimal
.branding
:primaryColorHex
andaccentColorHex
tokens preserved for generators (see DesignTokens).featureFlags
: Toggle modules (onboarding, auth, paywall, notifications).legal
: Set Privacy Policy and Terms URLs.
Secrets (Config/Secrets.swift
)
supabaseURL
,supabaseAnonKey
telemetryDeckAppID
revenueCatAPIKey
aiBackendBaseURLString
(default ishttp://127.0.0.1:5001
)accountDeletionURLString
(optional HTTPS endpoint)- Sign in with Apple placeholders (optional for future use)
Best practice: keep real secrets out of git; use local Secrets.swift
.
Theme colors (Core/Theme/DesignTokens.swift
)
Set primaryHex
and accentHex
once. UI uses DesignTokens.primaryColor
and DesignTokens.accentColor
.
Bundle identifier
- Central:
project.yml
→PRODUCT_BUNDLE_IDENTIFIER
- Or update in Xcode under Signing & Capabilities.
Assets
- App Icon:
Resources/Assets.xcassets/AppIcon.appiconset
- Logo (optional): add
AppLogo
image to Assets (used byLogoView
).
Localization
Strings live in Resources/Base.lproj/Localizable.strings
. Strings containing “APP_NAME” automatically replace with AppConfig.appName
at runtime.
Feature Reference
Onboarding (3 styles)
- Styles: Carousel, Highlights, Minimal. Set via
AppConfig.onboardingStyle
. - Pages: defined in
Modules/Onboarding/OnboardingModels.swift
with.defaultPages
. - Token replacement: onboarding copy supports dynamic
__APP_NAME__
.
Authentication & Profile
- Email+Password via
AuthRepository
with DI switching:- Supabase:
Backend/Supabase/SupabaseAuthRepository.swift
- Local fallback:
Backend/Protocols/AuthRepository.swift
(LocalAuthRepository)
- Supabase:
- Post-sign-in profile sheet if profile is missing:
Modules/Profile/ProfileSetupView.swift
+ ProfileRepository (Supabase / Local) - Sign in with Apple button is present but disabled by default (visible UI). Enable once your Apple config is ready.
Paywall & Subscriptions
- UI:
Modules/Paywall/PaywallView.swift
- Service:
Core/Services/PurchasesService.swift
- RevenueCat‑backed service when the SDK is present and
Secrets.revenueCatAPIKey
is set. Noop service otherwise; UI still works with placeholder offerings. - Root presentation: presented as a sheet when the app detects no active entitlement (driven by notifications from RevenueCat service).
- Settings integrates: Restore purchases, manage subscriptions (deep links), and shows plan/expiry.
Analytics
Core/Analytics/AnalyticsService.swift
- Uses TelemetryDeck v2 or TelemetryClient v1 automatically when the package is available and
Secrets.telemetryDeckAppID
is set; otherwise Noop.
Notifications (Debug)
Modules/Notifications/NotificationsDebugView.swift
: request permissions, schedule local notifications, register for remote notifications, show last APNs token.- Service:
Core/Notifications/NotificationService.swift
AI Wrappers (optional)
- Tabs in Home: Text Generation (Chat), Image Generation, Vision.
- Client:
Core/Services/AIApiClient.swift
→ calls your Flask backend (Secrets.aiBackendBaseURL
).
Local Data Demo
Modules/Demo/LocalDataDemoView.swift
withLocalCoreDataRepository
andCoreDataStack
.- Demonstrates programmatic Core Data model + CRUD.
Theming
Core/Theme/DesignTokens.swift
for colors.Core/Theme/Theme.swift
providesAppTheme
and.appTheme
environment.- Optional glass style is supported in components and can be toggled if you adopt a UI control for
AppTheme.style
.
App Shell & Routing
- Root:
Core/Root/TheSwiftKitApp.swift
andCore/Root/RootView.swift
withNavigationStack
. - Router:
Core/Routing/AppRouter.swift
with enumAppRoute
for typed navigation. - DI:
Core/DI/DIContainer.swift
selects repositories/services based on config + available SDKs. - Debug harness:
Modules/Demo/TestDriveView.swift
is shown by default inDEBUG
for quick path testing and shortcuts.
Backend Setup
Supabase (Auth, Profiles, Avatars)
Prerequisites:
- Auth: Enabled in your Supabase project.
- Profiles table: Add
public.profiles
with fieldsid (uuid)
,name
,gender
,contact
,avatar_url
,updated_at
. - Storage: Create
avatars
bucket; set RLS/policies as needed.
Profile repository: iOS uses SupabaseProfileRepository
to read/write profiles and upload avatars. Ensure RLS policies allow users to select/insert/update their own profile row and storage objects.
Subscriptions table + webhook mirror (optional, recommended)
- SQL: run
Backend/Supabase/sql/001_user_subscriptions.sql
and002_user_subscriptions_enhancements.sql
. - Edge Function: deploy
Backend/Supabase/edge/user_subscriptions_webhook.ts
. - Maps RevenueCat webhook events to
user_subscriptions
table (plan/expires/product_id). This enables server‑side truth for subscription status and is optional if you solely rely on RevenueCat client info.
RevenueCat (Paywall)
- Create products and offerings in RevenueCat; align your app’s packages to real products. Paste your public API key in
Secrets.swift
. - For recommended restore behavior (avoid cross‑account mismatches), consider disabling automatic transfer to new app user IDs in RevenueCat project settings.
AI Backend (Flask, optional)
- Install Python packages:
pip install -r Backend/Python/requirements.txt
- Set
OPENAI_API_KEY
in your environment (do not hardcode). - Start the server:
python Backend/Python/app.py
(default port 5001). - Health check:
GET http://127.0.0.1:5001/health
→{ "ok": true }
- iOS side: set
Secrets.aiBackendBaseURLString
to your server URL.Info.plist
includes ATS exceptions for127.0.0.1
andlocalhost
for dev.
How The Pieces Fit
- DI container chooses adapters by
AppConfig.backend
: Auth/Profile/Subscription repositories switch between Local and Supabase. - Purchases service switches between Noop and RevenueCat depending on SDK presence and API key.
- Analytics service switches between TelemetryDeck/TelemetryClient/Noop depending on SDK and app ID.
- Events and Notifications:
Core/Utils/AppEvents.swift
definesNotification.Name
keys and payload keys used across Settings and Root. - Logging:
Core/Logging/Logger.swift
providesAppLogger.log
for debug logging. - Strings: Use
NSLocalizedString
andLocalizedStringKey
throughout. The runtime replaces “APP_NAME” tokens in localized strings withAppConfig.appName
.
Step‑by‑Step Setup
- Clone the repo and open the project.
- Create secrets: Copy
Config/Secrets.sample.swift
→Config/Secrets.swift
. Fill Supabase URL/key, RevenueCat key, TelemetryDeck App ID, AI base URL, and optional account deletion endpoint. - Configure app settings:
- Edit
Config/AppConfig.swift
:appName
,backend
(.supabase
or.local
),onboardingStyle
,featureFlags
, legal URLs - Edit
Core/Theme/DesignTokens.swift
:primaryHex
andaccentHex
- Edit
- Bundle ID and signing: Update
project.yml PRODUCT_BUNDLE_IDENTIFIER
(or via Xcode Signing & Capabilities). Select your development team and fix signing if needed. - Assets: Place your icons in
AppIcon.appiconset
. Add anAppLogo
image (optional) for a branded logo in the UI. - Backend: Supabase → run the provided SQL migrations, configure RLS/policies, and set Secrets. RevenueCat → configure products/offerings and paste API key in Secrets. AI backend → run the Flask server locally or point to your hosted backend via Secrets.
- Build & run: In
DEBUG
, you can use TestDrive to quickly jump to screens or force onboarding/auth.
Enabling Sign in with Apple (Optional Later)
Currently the Sign in with Apple button is disabled visually. Once you have Apple credentials and backend wiring:
- Remove
.disabled(true)
on the button inModules/Auth/SignInView.swift
. - Wire the backend adapters to handle Apple sign‑in (e.g., Supabase GoTrue Apple OAuth).
Customization Tips
- Update UI copy in
Localizable.strings
(tokens for app name are replaced automatically). - To force onboarding again for testing, set
forceOnboardingOnce
totrue
(TestDrive has shortcuts). - To tweak paywall design, adjust
Modules/Paywall/PaywallView.swift
. - To change app‑wide tint, theme styles, or glass effect, use
DesignTokens
andAppTheme
.
Troubleshooting
- Packages fail to resolve: Ensure Xcode 15+ and a clean DerivedData before retrying.
- Supabase auth/profile issues: Check RLS policies; test with Supabase SQL console; ensure URL/key are correct.
- RevenueCat entitlements not updating: Confirm offerings configured; check sandbox account; look for events in RC dashboard; restart app to refresh cache.
- AI errors: Validate
OPENAI_API_KEY
; check Flask logs; test/health
and other endpoints with curl/Postman. - ATS/network: For dev on
127.0.0.1
,Info.plist
exceptions are included; for production, use HTTPS URLs.
Production Hardening
- Replace placeholder legal URLs with your real Privacy and Terms links.
- Remove or hide debug/testing screens for release builds (TestDrive remains DEBUG only).
- Consider locking down storage buckets (signed URLs) and tightening RLS as needed.
- Confirm that Secrets are not committed; use secure configuration management for CI/CD.
File Map (Edit Points)
- Secrets:
Config/Secrets.swift
(fromSecrets.sample.swift
) - App config:
Config/AppConfig.swift
- Theme colors:
Core/Theme/DesignTokens.swift
- Bundle ID:
project.yml
or Xcode signing settings - Assets:
Resources/Assets.xcassets/*
- Localized copy:
Resources/Base.lproj/Localizable.strings
That’s it — clone, duplicate Secrets, set AppConfig + DesignTokens, update bundle ID and assets, then run. The template adapts based on the SDKs and keys you provide, so you can start simple and layer on services when ready.