Code generation pipeline
All API-facing models are auto-generated from backend Zod schemas via a two-stage pipeline. This ensures the iOS app and backend always agree on data shapes.Two-stage codegen
Running the generator
Codable structs.
Shared between targets
All generated files are included in both the main app target and the widget target (SightscreenWidget). This guarantees that the widget’s Live Activity rendering uses the exact same types as the main app.
Generated model files
LiveActivityModels.generated.swift
The primary generated file for Live Activity payloads. Contains the full display state hierarchy.LiveActivityAttributes is set once at creation time and cannot change. ContentState is updated with every push. Anything that changes during a match must be in ContentState.FollowModels.generated.swift
Models for the follow/unfollow system.HubAPIModels.generated.swift
Models for the main hub/schedule API responses.Hand-written models
Some models are hand-written because they contain client-side logic or do not map to a backend schema.Auth models
Core models
Model conventions
All models (generated and hand-written) follow these conventions:JSON decoding strategy
The app configures a sharedJSONDecoder with ISO 8601 date support that handles both fractional seconds and standard formats.
The dual-format decoder exists because some backend responses include fractional seconds (e.g.,
2024-03-15T10:30:00.000Z) and others do not (e.g., 2024-03-15T10:30:00Z). Both must decode correctly.