Skip to content

TestFlight diagnostic build: HealthKit logging + permission fixes - #30

Draft
gsbernstein wants to merge 5 commits into
masterfrom
cursor/healthkit-diagnostics-999a
Draft

TestFlight diagnostic build: HealthKit logging + permission fixes#30
gsbernstein wants to merge 5 commits into
masterfrom
cursor/healthkit-diagnostics-999a

Conversation

@gsbernstein

@gsbernstein gsbernstein commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Purpose

TestFlight diagnostic build for a tester who cannot load HealthKit sleep data. Adds local logging with a share/copy flow in Settings — no third-party analytics.

Now merged up to date with master, which independently rewrote HealthKitManager to use HKSampleQueryDescriptor / HKSourceQueryDescriptor with proper awaiting (#40), added an observer query with background delivery, and already carries the SwiftData store-reset recovery. All of that is kept; the diagnostics layer is re-applied on top.

What this adds

  • DiagnosticLogger — in-memory log (capped at 500 entries) covering ModelContainer open, HealthKit availability and authorization, sample queries, source discovery, sample processing, and permission state transitions.
  • Settings → Diagnostics — live HealthKit state, sample and log counts, plus Share Diagnostic Logs, Copy Logs to Clipboard, and Retry HealthKit Access (which also reloads available sources).
  • requestAccessFromUser() — backs Grant Access and the Settings retry. Unlike requestAuthorization(), it always re-presents the HealthKit prompt instead of short-circuiting once the app has asked before, shows a spinner, and surfaces errors. When the reload returns zero samples it points the user at Settings → Health → Data Access & Devices.
  • SharePresenter — presents UIActivityViewController from the topmost view controller. Nesting a SwiftUI .sheet inside the Settings sheet caused the share sheet to dismiss itself and take Settings with it.

For the tester

  1. Install this build from TestFlight
  2. Open the app and tap Grant Access (or Retry HealthKit Access in Settings)
  3. Go to Settings → Diagnostics
  4. Tap Share Diagnostic Logs or Copy Logs to Clipboard
  5. Send the logs over

Reading the logs

  • requestAuthorization returned followed by rawSamples=0 suggests read access is denied — check Settings → Health → Data Access & Devices → Bedger → Sleep
  • Sleep sample query failed: … is an actual HealthKit error with its message
  • Discovered N sources with N > 0 but 0 sessions after filtering points at source exclusions or sleep-stage parsing

Note

ContentView still inserts UserPreferences from a computed property read during body evaluation (inherited from master). That is a latent SwiftUI/SwiftData issue, not the cause of the reported crash — the crash log pointed at the ModelContainer fatalError, which master now recovers from. Worth fixing separately against current master.

Open in Web Open in Cursor 

cursoragent and others added 5 commits July 24, 2026 14:27
- DiagnosticLogger records HealthKit bootstrap, queries, and state changes.
- Settings Diagnostics section: share/copy logs, retry HealthKit, live state.
- Grant Access always calls requestAuthorization and shows loading/errors.
- Bootstrap tries silent data load first; only prompts when zero samples.
- Await HK queries, recover from SwiftData store failures, fix preferences seeding.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
Make log() nonisolated so it can be called from BedtimeApp's static
ModelContainer initializer. Move UI-published mutations to @mainactor
record() and remove init-time logging that referenced shared during init.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
Present UIActivityViewController from the topmost view controller instead
of nesting a SwiftUI sheet inside the Settings sheet.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
Master rewrote HealthKitManager to use HKSampleQueryDescriptor /
HKSourceQueryDescriptor with proper awaiting (#40), added an observer query
with background delivery, and already carries the SwiftData store-reset
recovery. Kept all of that and re-applied the diagnostics layer on top:

- DiagnosticLogger instrumentation across container open, auth, queries,
  source discovery, sample processing, and permission state transitions.
- requestAccessFromUser() for Grant Access / Settings retry, which always
  re-presents the HealthKit prompt instead of short-circuiting once asked.
- Settings Diagnostics section with share/copy logs and retry, now also
  reloading available sources after a retry.

Dropped the superseded fetchSleepDataForDisplay/discoverAvailableSources
continuation wrappers in favor of master's descriptor-based queries.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
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