Skip to content

Add Apple Watch companion app - complications, full data views, remote commands - #642

Open
aug0211 wants to merge 13 commits into
loopandlearn:devfrom
aug0211:auggie-watch
Open

aug0211 wants to merge 13 commits into
loopandlearn:devfrom
aug0211:auggie-watch

Conversation

@aug0211

@aug0211 aug0211 commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a watchOS companion target (LoopFollowWatch) providing glanceable BG, remote controls (bolus, meal, override, temp target), and Nightscout/Dexcom Share data fetching. Reliable command delivery via APNS time-sensitive alerts. Independent from phone - parents can now go phone free and manage for kiddos directly from Watch!

Note: tested for 6 weeks (and counting) as our daily driver across Apple Watches from our son (T1D), mom, and dad for all Trio commands (meals, FPU, boluses, overrides, temp targets, dosing decisions). Loop needs to be tested.

Motivation

Why this matters: parents of T1D kids managing care across iPhone + watch, gap in current LoopFollow for watchOS users, etc. Full remote visibility and control from watch, fully independent of phone. Parents are no longer tied to a phone to manage T1D for their children.

What's Included

  • Watch target with BG chart and complications
  • Double tap to zoom in, triple tap to zoom out, scroll forward and backward with crown
  • Top level stats update on main screen while scrolling through time
  • Remote control views (bolus, meal, override, temp target)
  • Easter eggs for celebrations randomly on remote commands - surprise and delight (my wife and son fight over who gets to send remote commands now!)
  • Stats view on watch for past 24 hr

Testing

  • Three in vivo Apple Watch devices, WatchOS 26, Nightscout, Trio
  • Apple Watch Series 10 + iPhone Air
  • Apple Watch Series 10 + iPhone 15 Pro
  • Apple Watch Ultra + iPhone 17 Pro

Photos

incoming-AE295971-88BD-4BB1-BA4F-2178E8DFDB14 incoming-884BD748-8D0B-429F-B58C-5224850914EC incoming-1F9306E4-4027-4B1F-9C00-34D7AE0B23B5 incoming-2CF8CBC4-42DE-4D7D-A6A8-4BC2B78BD04E incoming-BF38DB69-452F-4E4A-9B5C-6FA4D4BC00E8 incoming-14E2C32E-25CE-437B-A63C-A354AFD75452 incoming-DFE7FB2E-AD96-4EA6-917E-DC30DA2986ED incoming-59A9253F-66B5-4393-A9B5-1C4194F9E619 incoming-180393C7-8F7E-47E5-872E-70D396DF560C incoming-F553893C-4182-4694-A0C7-3FD19D7D10DE incoming-0FF21A9F-2805-42AF-8EEB-0A90D3004DC3 incoming-44348644-518E-49F6-B564-C63FFDB7BEC9 incoming-5431889C-B541-49A3-873B-31328D003B90 incoming-92EE8B33-D062-4F50-973E-881B1F4B2CAD incoming-52E02158-2850-4B83-A4DB-498F77C165AB incoming-265FD586-5601-4173-86FC-11B1FCBFE519 incoming-51FB9789-37FA-4DDB-8B00-BC2B3F48C7CA incoming-AF6DECD2-D84B-4A3D-994B-E2020BC2E34E incoming-A264866E-09B9-4321-8CFA-EC9EC9C9DEBB incoming-93C2845D-F42E-45D4-849C-451F4C607A57 incoming-DF3282EF-01B2-4CF9-AFAA-19B44A8F5381 incoming-4932960F-5155-4692-B039-D5E633E9C0AF incoming-AFEF51F4-02F1-4ADB-B94C-256F599AB0BC incoming-D50616C6-5C7C-40C1-B956-60D03CD368C1 incoming-FDD90003-686D-47A3-8D77-D8AC93C2595D incoming-685F1960-79E5-4E66-B6BA-90887B0FCAC7

aug0211 and others added 3 commits May 8, 2026 00:33
Watch app with BG chart, remote controls (bolus, meal, override, temp target), and Nightscout/Dexcom Share data fetching. APNS push uses alert type with time-sensitive delivery for reliable command delivery.

Isolated watch-only changes on top of latest upstream dev — no unrelated iOS feature modifications.
- Complications for rectangle, circle, also bolus/meal/override/temp deep link shortcuts
- Dynamic BG color integrated throughout experiences
- Stats view on watch
- LoopStatus view on watch
- Cleaned up crown rotation requirements
- Watch was reading top-level `token` from /api/v1/status.json but Nightscout nests it under `authorized.token`
- POST treatments now actually authorize
- Cached APNS JWTs for 55 min (with 403-invalidation) instead of re-signing P256 on every send
- Forwarded LF APNS creds over WCSession so Trio return-notifications land on the iPhone
@aug0211 aug0211 changed the title Auggie watch Add full Apple Watch companion app - complications, full data views, remote commands May 8, 2026
@aug0211 aug0211 changed the title Add full Apple Watch companion app - complications, full data views, remote commands Add Apple Watch companion app - complications, full data views, remote commands May 8, 2026
aug0211 added 3 commits May 8, 2026 10:46
- Apply SwiftFormat auto-fixes to resolve CI lint failures
- Changes include indentation, file headers, spacing around operators, unused argument markers, brace wrapping, trailing commas, sort imports, and redundant self removal
- Covers ~25 files in LoopFollowWatch, LoopFollowWidgets, and LoopFollow/Watch.
- PhoneSessionManager.swift: added back in mealWithFatProtein, maxProtein, and maxFat to the buildConfig() dictionary so they're actually sent to the watch
- RemoteSettingsViewModel.swift: added PhoneSessionManager.shared.sendConfig() in $mealWithFatProtein so toggling it immediately pushes the new config to the watch
- BGFetcher.swift: add completion handler to fetchDeviceStatus so bolus screen can await fresh IOB/COB
- WatchBolusView.swift: fetch latest device status on appear with loading overlay to prevent stale COB double-counting
aug0211 added 3 commits May 8, 2026 19:52
- COB could under report by not including freshly entered COB in meal entry flow during bolus screen
@aug0211

aug0211 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

@bjorkert please consider this. Multiple users in our family now using it for months and it's a game changer. It's all of our preferred interface for managing T1D at this point. I'd like to bring this to more users who will also benefit from it.

@codebymini

Copy link
Copy Markdown
Collaborator

I’m concerned this PR introduces significant visual inconsistency with existing Loop Follow design patterns (colors, iconography, typography), and also includes an app icon change for Watch.

  1. High: BG color semantics diverge from current app behavior
  1. Medium: App icon change is included in this PR (Watch target)
  1. Medium: New watch screens use stronger custom color blocks than existing app style
  1. Medium: Iconography for similar actions is inconsistent with existing Loop Follow flows
  1. Medium: Typography treatment differs from existing app patterns

Request:
Please align Watch/Widget color semantics, icon choices, and typography with established Loop Follow patterns, and clarify whether the Watch app icon change is intended in this PR.

@aug0211

aug0211 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

I’m happy to address concrete issues, but I don’t agree that visual differences from the iOS app should, by themselves, block this PR.

BG colors: The color question is fair. This uses the dynamic BG coloring that I authored and that was merged into Trio, which I previously shared with LoopFollow as well. The implementation here is consistent with that work, rather than an arbitrary new color scheme. A specific concern about how that interacts with LoopFollow’s warning semantics is worth discussing, but we should distinguish that from a general objection to using different colors. This is a trivial refinement to be made and easily handled post-merge as an iteration. Certainly should not be a blocker toward much bigger picture progress. You may even find that you love it, as is and was the case with many Trio users.

Watch app icon: The Watch target needs its own app icon asset. The supplied image is a resized version of the existing iOS icon, not a redesign or an intended branding change. Could you provide a screenshot or identify exactly what looks different? Adding the asset required for the Watch app is not, by itself, a change to the app’s visual identity. I'm concerned about whether this review received appropriate human oversight before potential LLM review output was copy/pasted.

Buttons, action icons, and typography: This is a watch app, not the iOS app on a smaller screen. The stronger visual differentiation is intentional, given the smaller display and the need to distinguish information and actions at a glance. I’m open to refining individual symbols and typography where that improves clarity, but matching the iOS presentation is not automatically the right outcome for watchOS. We should evaluate whether these choices work well on the device, rather than treating differences alone as defects. Again, easy to iterate on post-merge and would be a shame to blocker much bigger picture progress for trivial color tweaks that can be made post-merge.

Have you built and tested this on a watch? Please clarify which concerns reflect behavior you observed while using it and which come from source review. Both can be useful, but for any proposed merge blocker, I’d like to understand the specific user-facing problem and the expected behavior. That gives us something concrete to resolve.

My position is that we should merge this and iterate on nonblocking refinements afterward. Broader styling preferences can be tracked separately and refined through follow-up PRs, informed by actual use. Let's get this merged so (1) users can benefit immediately from the functionality and (2) contributors can build on top of it to iterate and make it better. This also reduces future merge conflict risk.

There is a cost to delaying useful functionality, too. We should not keep these capabilities out of users’ hands solely because there are visual details we may choose to refine. Let’s resolve concrete blockers, merge the feature, and continue improving it rather than letting perfection become the enemy of progress.

@codebymini

codebymini commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator
Screenshot 2026-09-17 at 13 50 07 There is clearly a difference in the app icon used. Using a LLM to respond does not change that

@codebymini

Copy link
Copy Markdown
Collaborator

I do not agree that design consistency is non-blocking in this case. Consistency between the iOS app and Watch app is a core UX requirement, not optional polish. People shouldn’t have to relearn what colors mean or where to look for key actions just because they switched devices.

@aug0211

aug0211 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

The Watch PNG reuses the earlier LoopFollow iOS icon unchanged. Both have the same Git blob hash (8c1c15231e3b35288c91bbdbf211af3a91f57a90). The glossy iOS artwork was introduced in a8fe94f. This is an asset-version difference, not a newly designed Watch identity.

This is a minor cosmetic refinement that should be handled iteratively, not a reason to block the entire Watch feature. We should keep the review effort proportionate to the issue. Spending more time debating a flat versus glossy version of the same logo, while delaying useful functionality for the community, is not a good tradeoff.

There is also a technical reason not to assume copying the baked-in gloss is the best outcome. Apple’s app-icon guidance explicitly recommends: “Let the system handle blurring and other visual effects.” It warns that custom, static effects can interfere with the system’s dynamic effects. A layered Icon Composer asset, with the system handling the material effects and supported appearance modes, may be a better approach to system-wide consistency than reproducing static shading in another PNG.

That is a reasonable follow-up improvement across both targets, not an additional prerequisite for delivering the Watch functionality.

My proposal remains: merge the feature, track cosmetic refinements separately, and iterate. There is a real cost to keeping useful capabilities out of the community’s hands while we debate details that can readily be improved afterward. We do not need to settle every visual preference before users can benefit.

If we really think somehow this is meaningful use of our time and worthy of holding big picture functionality updates back from the community, I'm sure either of us can submit a PR to force the static and non-dynamic BG color display and an app icon update to force liquid glass into the icon itself.

The Watch app icon carried a superseded revision of the LoopFollow mark
(the flat ring) while the iOS app has since moved to the glossy artwork
rendered from loopfollow-icon.svg. Replace it with the shipping asset so
both targets present the same identity.

The Watch PNG is now byte-identical to the iOS icon
(blob a975ee0), so this is an asset
version alignment rather than a new Watch design.

Contents.json is unchanged: same filename, same watchos 1024x1024 entry.
The iOS-only dark and tinted appearance variants are deliberately not
copied, as watchOS does not consume them.
Dynamic BG coloring was unconditional on the Watch and in the
complications, which diverged from the iPhone app's threshold coloring
with no way to opt out. Add Settings > General > Display > Dynamic BG
Color and have all three surfaces honor it.

Off (the default) colors from the iPhone's existing scheme everywhere:
yellow at or above the high threshold, red at or below the low one,
green between. On uses the existing hue ramp on iPhone as well as the
Watch and complications.

The ramp in bgDynamicColor is unchanged; the iPhone copy is byte
identical to the Watch and complication copies, matching how the
targets already duplicate WidgetData.

The new toggle is nested under Color BG Text, which stays the master
switch, so the two settings cannot contradict each other.

Coloring thresholds are resolved on the phone before syncing because
they depend on timeInRangeMode, which the Watch never receives; sending
lowLine/highLine instead would silently mismatch the phone in the .tir
and .titr modes. Complications read the synced values from the App
Group, which the Watch already mirrors for Nightscout credentials.
Color BG Text governs only the current-BG number on the iPhone's main
screen; the graph colors its points unconditionally in
BGChartModel.colorFor. Routing the Watch's chart through that setting
was wrong and turned points, the sparkline fill and the BG bar gradient
white when it was off.

Split the resolver in two. Charted values use bgPointColor, which is
always colored and picks between the threshold scheme and the hue ramp
based on Dynamic BG Color alone. The current-BG number uses
bgTextColor, which falls back to .primary when Color BG Text is off.

Complication BG numbers follow the main-screen number; complication
sparklines follow the graph.
The setting reached the BG number and the Watch but not the iPhone's own
chart, which still colored every point from the thresholds. Branch
colorFor on the setting so points and line runs use the hue ramp when it
is on, and mark the chart dirty when it is toggled so the graph rebuilds
on return to the main screen, the same way the time zone toggles do.

Color BG Text is deliberately not consulted here: it governs the BG
number only, so the graph stays colored either way.
@aug0211

aug0211 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Updated to use the latest icon.

Updated graph coloring to match the phone based on phone setting (including the existing toggle in display settings for white vs color, and a toggle for dynamic if color is enabled). Defaults to off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants