Bundling First-Screen Values into One Response: home-summary

The API contract that returns parking, outing, forecast, and source status for the first screen

Hangangjari’s first screen combines parking lots, current values, forecasts, crowding, events, facility summaries, directions candidates, and source checks. When the client composes several responses, success state and refresh time can diverge between sections.

The parking section may have just refreshed while the event section is stale. The forecast may use a different horizon, and the widget may show a different refresh state from the app.

The server bundles first-screen values into one response so sections and widgets share a reference time.

First-Screen Values in One Request

home-summary provides the first values that the app and widgets display for one park in a single request.

flowchart LR
  API["Per-park first-screen response"] --> Park["Park"]
  API --> Parking["Parking aggregate<br/>lot status"]
  API --> Forecast["Parking forecast<br/>park crowd forecast"]
  API --> Outing["Outing summary<br/>signals / facility groups / directions"]
  API --> Freshness["Refresh state<br/>source checks"]

With separate calls, the app must fetch lot lists, current values, forecast overview, outing overview, and source checks independently. This creates several first-screen problems.

  • Success and failure can diverge across calls.
  • Part of the screen can remain on a previous park.
  • Widgets cannot comfortably handle multiple network calls.
  • Cache and freshness checks become more complex.
  • iOS decoding needs a wider defensive surface when the API changes.

The server determines each section’s value and refresh state in one payload.

Fields enter home-summary only when they are immediately needed on the first screen. Excluding long lists and raw payloads used only on detail screens limits response size and change scope.

Four Response Groups

The iOS value is divided into four large parts.

FieldRole
parkConfirms which park this summary is for
parkingParking aggregate, recommended lot, lots, and statuses
forecastForecast horizon and parking/park crowd overview
outingGeneral-screen signals, facility groups, directions, and source checks

The app’s parking screen reads its parking overview from HomeSummary, and the general screen reuses compact data.

flowchart TB
  HomeSummary --> ParkingOverview["ParkingOverview value"]
  HomeSummary --> OutingOverview["Partial OutingOverview value"]
  HomeSummary --> WidgetParking["Parking widget snapshot"]
  HomeSummary --> WidgetGeneral["General widget snapshot"]

The client splits the server response by screen. Parking overview, general park summary, and widget snapshots start from the same response, reducing duplicate calls and time differences during screen transitions.

Compatibility with Existing App Versions

iOS apps update more slowly than servers, creating a period when older apps read a new server payload. home-summary preserves existing field meanings during this period.

The rules are:

  • Preserve existing required fields.
  • Start new values as optional fields or nested-object additions.
  • Enums must define behavior for unknown values.
  • Do not change the meaning of date and freshness fields.
  • If the park ID differs from the requested value, do not trust the payload.

The widget loader follows the same approach. It treats a network home-summary as empty when its park ID does not match the request, preventing cache contamination.

iOS Cache for the First-Screen Response

iOS stores the received HomeSummary in SwiftData and reflects the inner park, lots, statuses, and forecast overview into their respective caches.

sequenceDiagram
  autonumber
  participant Store as App state store
  participant Repo as Parking repository
  participant API as Hangangjari API
  participant Cache as SwiftData cache

  Store->>Repo: Check stored first-screen value
  alt Cache is fresh
    Repo-->>Store: Return cached first-screen value
  else Stale or missing
    Repo->>API: Request first-screen response
    API-->>Repo: Return first-screen response
    Repo->>Cache: Store first-screen value
    Repo->>Cache: Update park/parking/status/forecast caches
    Repo-->>Store: Return new first-screen value
  end

The first screen and detail screens start from the same response. When the user enters parking detail, the app reuses the value it just received.

Freshness in the Server Cache

The server keeps both a fast-response cache and a last-success response cache for home-summary. When a rebuild succeeds, both caches are updated. If rebuilding fails, the last successful response can be returned.

HTTP responses receive Cache-Control: private and ETag, allowing the same app instance to receive 304 for repeated first-screen requests in a short period.

When returning a stale backup, the server preserves freshness state and source-check results in the payload.

A Shared Reference Time for App and Widget

home-summary provides one first-screen value shared by app screens, widgets, and cache. The client validates the requested park against the response park and preserves existing meaning as new fields are added. When the server returns stale cache, it retains freshness state so the UI identifies the value as the last confirmed response.

Comments

Comments

    Image preview