Core philosophy
The iOS app is a dumb view layer. The backend owns all formatting, string construction, and business logic. The app’s job is to receive pre-formatted data and render it.What the iOS app does NOT do
- Format scores, overs, run rates, or player stats
- Decide what to show based on match state (e.g., innings break vs. live)
- Apply conditional logic to determine display layouts based on match phase
- Transform raw data into user-facing text
What the iOS app DOES do
- Render pre-formatted display states from the backend
- Manage UI navigation and presentation
- Handle device-level concerns (Live Activities, push tokens, permissions)
- Cache and poll for data
- Send user actions back to the backend
MVVM with @Observable
The app uses MVVM powered by Swift’s@Observable macro (Observation framework).
| Layer | Responsibility |
|---|---|
| View | SwiftUI views that read from observable models and render UI |
| ViewModel | @Observable classes that hold view state and call services |
| Service | Protocol-based services that fetch, cache, and mutate data |
| Backend | Source of truth for all data and display formatting |
ViewModels are
@Observable classes, not ObservableObject with @Published. This uses the newer Observation framework available from iOS 17, with backcompat handled where needed.Dependency injection
DI is done through SwiftUI’s@Environment. Each service protocol has an EnvironmentKey extension, and views access services declaratively.
- Real — hits the actual backend API
- Fake — returns canned data for previews and testing
Data flow
Backend returns pre-formatted data
The API responds with display-ready models — formatted strings, ordered arrays, resolved image URLs.
Service layer fetches and caches
Protocol-based services make the API call, decode the response, and cache results in memory.
ViewModel exposes state
@Observable view models hold the decoded data. SwiftUI views automatically re-render when properties change.Views render
SwiftUI views bind directly to view model properties. No transformation — just layout and styling.
Tech constraints
| Constraint | Value |
|---|---|
| UI framework | SwiftUI only (no UIKit) |
| Minimum iOS version | 16.1 |
| Reason for iOS 16.1 | Live Activities require ActivityKit, available from iOS 16.1 |
| Architecture | MVVM with @Observable |
| DI mechanism | @Environment with protocol-based services |
| Data format | All display data pre-formatted by backend |