Run a Match from Your Smartwatch
If you referee or manage matches, you can run a whole game from your wrist — start the match, log goals, cards, fouls and substitutions, then end it — without taking the phone out of your pocket. This guide is the step-by-step companion to the Smartwatch Companion overview, focused purely on the live-match flow.
There is no automated watch-tester in the QA toolchain — the platform tester agents drive the phone app, the web app and the backend, but none of them can drive a Wear OS or watchOS build. Every step below has to be checked by hand on a paired phone plus a real watch or watch emulator. Treat the flows here as manually verified, not auto-tested.
Before you start
The watch is a thin companion. It never talks to the 4league backend on its own — every tap on the wrist is relayed to the paired phone, which makes the real API call and sends the result back. Three things must be true before the live-match flow works:
- The phone is nearby and reachable — Bluetooth range, watch paired.
- The 4league phone app is running — open or backgrounded, but not force-quit. If it is killed, the relay is dead and the watch falls back to its waiting screen.
- The session has synced — on launch the phone pushes a
SESSION_SYNCenvelope to the watch. Until that arrives, the watch has no signed-in user and shows the waiting screen.
Only users who can edit a match see it on the watch: the competition organizer, an assigned referee, or a Team Manager of one of the two teams. Fans, players and followers never get live-match controls on the wrist. The phone computes the editable-match list against your live session and pushes only those matches to the watch — the watch itself does no permission checks and never queries the backend for matches.
How a tap reaches the backend
Knowing the round-trip explains every "why isn't it working" case below. A single action — say, adding a goal — travels like this:
Add goal — the round trip ├── Watch — you tap a side / pick a scorer ├── Watch → Phone — ACTION_REQUEST (JSON on path /fourleague) ├── Phone → Backend — the real authenticated API call ├── Backend → Phone — result └── Phone → Watch — ACTION_RESPONSE, the wrist UI updates
So if the watch seems to "hang" after an action, the break is almost always between the watch and the phone (out of range, app force-quit) or the phone and the backend (no connectivity) — not on the watch itself.
Step 1 — Open the match list
Open the 4league phone app and sign in
As soon as the phone sees a reachable watch with the companion installed, it pushes your session over automatically. No separate login exists on the watch.
Raise your wrist and open the 4league watch app
The waiting screen resolves once the session envelope lands. The watch then shows the match list — only the matches you can edit.
Tap the match you want to run
This opens the live-match screen with the score, running clock and team crests.
The watch is built for the touchline, not for browsing — the list only carries matches that are kicking off within roughly the next 10 minutes or already in progress. If your next game is an hour away, the watch shows an empty list on purpose. Open the match a few minutes before kick-off and it will appear. (An empty list can also mean you have no editing rights on any near-term match, or the session hasn't synced yet.)
Step 2 — Run the match
From the live-match screen the full action set is available on Wear OS:
| Action | How to do it on the wrist | What it sends |
|---|---|---|
| Start match | Tap Start on the live-match screen for a not-yet-started game. | ACTION_REQUEST → phone starts the clock server-side |
| Add goal | Tap the score / a side to open GoalEntry, pick scorer (and assist). | ACTION_REQUEST → goal logged, score updates |
| Add card | Long-press to open the ActionMenu → Card → yellow / red. | ACTION_REQUEST → card logged |
| Add foul | Long-press → ActionMenu → Foul. | ACTION_REQUEST → foul logged |
| Substitution | Long-press → ActionMenu → Substitution, pick out / in. | ACTION_REQUEST → sub logged |
| End match | Tap End on the live-match screen. | ACTION_REQUEST → phone finalizes the match |
The two gestures to remember: tap the score for a goal, long-press for everything else (the ActionMenu). Each action waits for the phone's ACTION_RESPONSE before the wrist UI reflects it, so a brief spinner after a tap is normal.
Wear OS screen flow
Wear OS — live match ├── WaitingScreen — pre-session ├── MatchListScreen — near-term / in-progress matches you can edit │ └── LiveMatchScreen — score, clock, Start / End │ ├── GoalEntryScreen — tap score → pick scorer + assist │ └── ActionMenuScreen — long-press │ ├── CardEntryScreen — yellow / red │ ├── FoulScreen │ └── SubstitutionScreen └── RankingsScreen — standings widget (all users, Wear OS only)
Wear OS vs. Apple Watch
Both companion apps exist — Wear OS (Kotlin / Jetpack Compose, under watches/wearos/) and watchOS (Swift / SwiftUI, under watches/watchos/) — and both share the same session handoff and the same "paired phone is the source of truth" model. The live-match action set, however, is only fully wired on Wear OS today.
| Step in this guide | Wear OS | watchOS (Apple Watch) |
|---|---|---|
| Open match list | ✓ | ✓ |
| Open a match (live screen) | ✓ | ⚠ Lands on a placeholder |
| Start / End match | ✓ | ⚠ View exists, not wired |
| Add goal | ✓ | ⚠ Placeholder |
| Add card | ✓ | ⚠ Referenced view undefined |
| Add foul | ✓ | ⚠ View exists, not wired |
| Substitution | ✓ | ⚠ Referenced view undefined |
On watchOS the only reachable flow today is WaitingView → MatchListView → a placeholder Text destination. The LiveMatchView, ActionMenuView and FoulView SwiftUI files exist in the source tree but are not attached to the navigation graph, and ActionMenuView references CardEntryView / SubstitutionView structs that aren't defined yet. So follow this guide on a Wear OS device for the full flow; on Apple Watch you can reach the match list but not yet run the game. The feature-parity table on the overview page tracks this.
The watch is a control surface for people who run matches, not a fan-facing live-scores ticker. There is no spectator screen that streams scores of matches you don't edit. The closest thing is the Wear OS Rankings widget — a glanceable standings position for your followed teams — and even that is Wear OS only; the watchOS app is match-control only and ships no rankings screen. To follow a match as a spectator, use the phone app.
Troubleshooting
| Symptom | Most likely cause |
|---|---|
| Watch stuck on the waiting screen | Phone app not open / force-quit, or out of Bluetooth range — no SESSION_SYNC received. |
| Match list is empty | No editable match kicking off within ~10 min or in progress; or you lack editing rights; or the session hasn't synced. |
| A tap spins, then nothing happens | The phone couldn't reach the backend, or the watch↔phone link dropped mid-ACTION_REQUEST. Re-check phone connectivity. |
| Apple Watch opens a match but shows no controls | Expected — the watchOS live-match screen is still a placeholder. Use the phone or a Wear OS watch. |
For pairing, session sync and the rankings widget, see the full Smartwatch Companion page. For running matches from the phone, see Match Management.