Getting Started

ShipThatApp is a production-grade SwiftUI starter built with MVVM, the modern @Observable macro, async/await, and @MainActor for UI work. This guide walks you from a fresh clone to a running app.

Requirements

Before you start, make sure your toolchain and accounts are ready.

  • Xcode 27 with the iOS 27 SDK (the project builds against the latest SDK).
  • Deployment target: iOS 17+ — the app runs on iOS 17 and later.
  • Swift 6 language mode.
  • A Supabase project for authentication.
  • A RevenueCat account for in-app purchases.
  • A TelemetryDeck app for analytics.
  • An OpenAI key for the cloud AI features. This key lives on your backend proxy only — it never ships inside the app.

Dependencies

Dependencies are managed with Swift Package Manager and resolve automatically when you open the project in Xcode. The boilerplate uses:

  • Supabase (supabase-swift) — authentication and backend access.
  • RevenueCat (v5) — in-app purchases and ready-made paywalls.
  • TelemetryDeck — privacy-first analytics.
  • KeychainSwift — secure on-device storage for tokens and credentials.

No GoTrue package

Authentication is handled through the supabase-swift package and the AuthManager class — there is no separate GoTrue dependency to add.

Step 1 — Clone the repository

git clone https://github.com/matious89pl/ShipThatApp.git
cd ShipThatApp

Step 2 — Configure your secrets

All sensitive keys live in a gitignored Config.xcconfig file, so your secrets never get committed. Start from the example template:

cp ShipThatApp/Support/Config.Example.xcconfig ShipThatApp/Support/Config.xcconfig

Then fill in your values. The keys the app reads are:

  • SUPABASE_URL — your Supabase project URL.
  • SUPABASE_KEY — your Supabase anon/public key.
  • RC_API_KEY — your RevenueCat API key.
  • TD_APP_ID — your TelemetryDeck app ID.
  • API_AUTH_KEY — the shared secret used to sign requests to your backend proxy (must match the backend's AUTH_SECRET_KEY).

These values are surfaced to the app through Info.plist and read at runtime from Bundle.main.infoDictionary. For example, AuthManager builds its SupabaseClient from SUPABASE_URL and SUPABASE_KEY, and Config.Api.authKey reads API_AUTH_KEY — none of them are hardcoded in source.

Never hardcode keys

Do not paste credentials into Info.plist directly, into AuthManager.swift, or anywhere else in source. Keys belong in the gitignored Config.xcconfig. The same rule applies to your OpenAI key: it stays on the secure backend proxy, which signs every request with HMAC, so the OpenAI key never ships inside the app.

Step 3 — Deploy the backend proxy

The cloud AI features (ChatGPT, DALL·E, and Vision) route through a secure backend proxy that signs every request with HMAC. Deploy the Express proxy (and the delete-account Supabase Edge Function used for in-app account deletion) before exercising those features, and set the backend's AUTH_SECRET_KEY to the same value you used for API_AUTH_KEY.

Step 4 — Update project settings

In Xcode, set your own Bundle Identifier, select your Team and signing certificates, and update the app name and display settings to match your product.

Step 5 — Build and run

Open ShipThatApp.xcodeproj in Xcode, choose a simulator or a physical device, and run (⌘R). With your Config.xcconfig populated, the app boots straight into the onboarding and authentication flow.