Skip to content

Fix launch crash, infinite spinner, and HealthKit data loading - #29

Draft
gsbernstein wants to merge 2 commits into
masterfrom
cursor/fix-launch-crash-999a
Draft

Fix launch crash, infinite spinner, and HealthKit data loading#29
gsbernstein wants to merge 2 commits into
masterfrom
cursor/fix-launch-crash-999a

Conversation

@gsbernstein

@gsbernstein gsbernstein commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Problem

TestFlight crash log confirms launch failure at BedtimeApp.swift:23fatalError when SwiftData can't open the store after the #20 schema change.

A follow-up report after delete/reinstall: app opens but shows an infinite loading spinner (nav bar visible, no cards). That matches permissionsRequestState stuck at .loading.

Root causes

1. SwiftData store incompatible after #20 (crash)

ModelContainer creation fails → fatalError before any UI loads.

2. Cancelled .task left HealthKit in .loading (spinner)

PR #29 initially combined preferences seeding and HealthKit fetch in one .task on a Group whose child identity changes when @Query populates. SwiftUI cancels that task mid-flight, so fetchSleepData's defer never runs and permissionsRequestState stays .loading forever.

3. HealthKit queries were fire-and-forget

loadSleepData() returned before HKSampleQuery callbacks, so the UI could leave loading before data arrived (explains "home screen but no sleep data").

Fix

  • Store reset recovery on ModelContainer failure (delete store + -shm/-wal, retry)
  • Preferences seeding in its own .task on the loading branch only; no insert during view body
  • HealthKit fetch started from HealthKitManager.init (not tied to view lifecycle)
  • resumeLoadingIfNeeded() safety net on main content
  • Await HK queries with continuations before returning from fetchSleepData

Verification

  1. Upgrade from old schema build → launches (settings reset)
  2. Fresh install / reinstall → no infinite spinner; cards appear
  3. With Garmin sleep data in HealthKit → recent sleep list populates
Open in Web Open in Cursor 

cursoragent and others added 2 commits July 23, 2026 18:20
- Stop inserting UserPreferences during view body evaluation; seed defaults
  in a task and gate the main UI on the persisted @query result instead.
- Recover from incompatible SwiftData stores by deleting stale files and
  retrying container creation (covers upgrades where delete/reinstall may
  still restore an old store via iCloud backup).
- Guard LastNightCard against an empty session array.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
- Start the initial HealthKit fetch from HealthKitManager.init so it is not
  cancelled when ContentView switches from the preferences seeding state to
  the main UI (which left permissionsRequestState stuck at .loading).
- Await HKSampleQuery results before returning from fetchSleepData so sleep
  data is populated before the UI leaves the loading state.
- Add resumeLoadingIfNeeded() as a safety net on the main content view.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
@cursor cursor Bot changed the title Fix launch crash on fresh install and schema upgrade Fix launch crash, infinite spinner, and HealthKit data loading Jul 23, 2026
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