iOS App Architecture

The iOS app follows the MVVM (Model-View-ViewModel) pattern with a service layer.

Layer Diagram

App Entry Point

StaccatoCoffeeApp.swift is the @main entry point:

@main
struct StaccatoCoffeeApp: App {
    @StateObject private var authViewModel = AuthViewModel()
    @StateObject private var cartViewModel = CartViewModel()
 
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(authViewModel)
                .environmentObject(cartViewModel)
        }
    }
}

Key responsibilities:

  • Initializes SupabaseManager singleton
  • Creates and injects AuthViewModel and CartViewModel as environment objects
  • Handles OAuth callback URLs (staccatocoffee://auth/callback)
  • Preloads menu data and modifier cache after authentication

ContentView.swift uses a TabView with role-based tabs:

TabViewRoles
HomeHomeTabViewAll
OrderMenuTabViewAll
OrdersStaffOrdersViewEmployee, Admin
AnalyticsAdminDashboardViewAdmin
RewardsRewardsTabViewAll
AccountAccountTabViewAll

A cart button overlay (top right) opens CartSlideOver.

File Structure

StaccatoCoffee/
├── App/
│   └── StaccatoCoffeeApp.swift        # @main entry point
├── Core/
│   ├── Environment.swift              # AppConfig enum
│   └── Extensions/
│       ├── Color+Brand.swift          # Brand colors
│       └── View+Extensions.swift      # View helpers
├── Models/                            # 6 data model files
├── Services/                          # 9 service files
├── ViewModels/                        # 7 view model files
└── Views/
    ├── ContentView.swift              # Tab container
    ├── Auth/                          # Login, Apple Sign In
    ├── Home/                          # Home tab, location picker
    ├── Menu/                          # Menu browsing, item detail
    ├── Cart/                          # Cart slide-over
    ├── Checkout/                      # Checkout, payments
    ├── Rewards/                       # Rewards tab
    ├── Account/                       # Profile, settings
    └── Staff/                         # Order queue, admin dashboard

Concurrency Model

The app uses Swift’s modern concurrency throughout:

  • async/await for all network calls
  • @MainActor on ViewModels for thread-safe UI updates
  • async let for parallel data fetching (e.g., MenuService.getItemDetails)
  • AsyncStream for observing auth state changes
  • Task {} blocks for launching async work from synchronous contexts

Caching Strategy

CacheStoragePurpose
MenuCacheUserDefaultsCategories, items, featured items
ModifierCacheIn-memory singletonModifier groups and modifiers
LoyaltyCacheUserDefaultsLoyalty account data
CartStorageServiceUserDefaults (staccato-cart)Shopping cart persistence