Sample CodeiOS, iPadOS, Mac Catalyst, watchOSReviewed 2026-07-26View on Apple Developer

Building a Localized Food-Ordering App

At a glance

Item Summary
Purpose Demonstrate localized strings, inflection, attributed text, formatted currency, dates, and a watch complication surface.
Architecture Two app targets: a SwiftUI food-order flow and a small watch app; both favor view-local state and Foundation value types.
Main state owner The iOS ContentView owns the current Order and presentation flow; detail views return new value objects by closure.

Project structure

Caffe/
├── Caffe/
│   ├── CaffeApp.swift
│   ├── Models/{Food,Order}.swift
│   └── Views/*.swift
└── CaffeCompanion WatchKit Extension/
    ├── CaffeWatchApp.swift
    ├── ContentView.swift
    └── ComplicationController.swift

The phone and watch folders are separate executable targets. The watch sample is a localized date view, not a synchronized order client.

Overall architecture

Reference code

Caffe/Caffe/Views/ContentView.swift:10 — the root view owns order and navigation state.

struct ContentView: View {
    // ...
}

Ownership and state

Ownership evidence

Caffe/Caffe/Views/FoodDetailsView.swift:10 — the detail receives parent selection and returns one completed value through a closure.

struct FoodDetailsView: View {
    // ...
}

ContentView is the order mutation authority. FoodDetailsView owns only draft selection state. ReceiptView receives an order value and owns only the editable tip. Static FoodItem instances form the in-memory catalog.

Class and protocol design

Type Responsibility Design
FoodItem, FoodSize, Ingredient Catalog, localization, and pricing Immutable or value-semantic model types
Order, OrderItem Cart items and derived totals Value types with computed properties
ContentView Feature composition and state transitions SwiftUI View
Detail/receipt/card views Focused presentation and local interaction SwiftUI composition
ComplicationController watchOS complication data-source hooks CLKComplicationDataSource

There is no app-defined service or repository protocol. Protocol orientation is limited to Swift value conformances and framework UI contracts.

Access control

Boundary Effect and rationale
private @State in feature views Only the owning view can mutate order, selection, sheet, quantity, or tip state.
private layout constants and action helpers Keeps presentation mechanics out of the view’s construction API.
Model and view types are implicit internal Both targets compile only the code they need; no public library surface exists.
Immutable let model fields Prevent partially mutated catalog entries and order items after construction.

Caffe/Caffe/Models/Food.swift:26 shows immutable catalog fields; Caffe/Caffe/Views/ReceiptView.swift:12 shows private receipt state.

Logic ownership and placement

Logic Owner
Catalog prices and localized names FoodItem / FoodSize
Quantity aggregation and totals Order / OrderItem
Order mutation and sheet flow iOS ContentView
Draft item construction FoodDetailsView
Tip and localized receipt description ReceiptView
watch date formatting Watch ContentView

Design patterns

Pattern Evidence Purpose
Value model Caffe/Caffe/Models/Order.swift:10 Makes order updates simple and local to SwiftUI state.
Unidirectional callback Caffe/Caffe/Views/FoodDetailsView.swift:12 Sends a completed item upward without sharing mutable draft state.
Composition Caffe/Caffe/Views/ContentView.swift:27 Builds the feature from small specialized views.
Framework data source Caffe/CaffeCompanion WatchKit Extension/ComplicationController.swift:10 Supplies watchOS complication hooks without app infrastructure.

Naming conventions

  • Model names use business nouns (FoodItem, OrderItem, Ingredient) and computed intent (totalPrice, localizedPrice).
  • Views use screen/component suffixes: FoodDetailsView, ReceiptView, and FoodHeaderView.
  • Event handlers state transitions: onSelectionComplete, onOrderComplete, and orderButtonTapped.

Architecture takeaways

  • Keep draft interaction state in the child and commit a complete value to the parent.
  • Put price and total calculations on value models, not inside layout code.
  • Treat phone and watch targets as separate composition roots unless synchronization is explicitly implemented.
  • Use access control to make SwiftUI state ownership obvious.

Source map

Source Role
Caffe/Caffe/CaffeApp.swift:10 iOS composition root
Caffe/Caffe/Models/Food.swift:10 Food catalog model
Caffe/Caffe/Models/Order.swift:10 Order model
Caffe/Caffe/Views/ContentView.swift:10 Feature state owner
Caffe/CaffeCompanion WatchKit Extension/ContentView.swift:10 Separate watch presentation