Skip to content

Fix permission card flash using PermissionsRequestState enum#16

Open
gsbernstein wants to merge 4 commits into
masterfrom
cursor/fix-permissions-startup-flash-cb59
Open

Fix permission card flash using PermissionsRequestState enum#16
gsbernstein wants to merge 4 commits into
masterfrom
cursor/fix-permissions-startup-flash-cb59

Conversation

@gsbernstein

@gsbernstein gsbernstein commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Problem

On every cold start, the app briefly showed the "HealthKit Access Required" card even for users who had already granted sleep data permissions. hasRequestedAuthorization defaulted to false, which conflated "still checking" with "needs permission."

Solution

Introduce PermissionsRequestState with three explicit cases:

  • .loading — startup authorization check in flight (ProgressView)
  • .shouldRequest — check finished; show permission card
  • .hasRequestedrequestAuthorization completed this session; show main content

fetchSleepData() now captures thrown errors into errorMessage before rethrowing, so the permission card shows an explanation when startup auth fails (even though .task uses try?).

Why no separate "has permission" case?

HealthKit does not report read authorization status for privacy — authorizationStatus(for:) is only meaningful for write/share types. For sleep read access, the only signal is whether requestAuthorization() completes (returning users reach .hasRequested silently without the system sheet).

Open in Web Open in Cursor 

cursoragent and others added 2 commits June 28, 2026 14:14
Persist HealthKit authorization request state across launches and show a
loading indicator while the initial authorization check runs, instead of
defaulting to the permission card before async HealthKit work completes.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
Represent loading as nil, needs-permission as false, and ready as true.
Removes the separate isCheckingAuthorization flag and UserDefaults persistence.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
@cursor cursor Bot changed the title Fix permission card flash on startup for returning users Fix permission card flash on startup using optional auth state Jun 28, 2026
Replace optional Bool with loading, shouldRequest, and hasRequested cases.
Document why read grant status is not a separate enum case.

Co-authored-by: Greg <gsbernstein@users.noreply.github.com>
@cursor cursor Bot changed the title Fix permission card flash on startup using optional auth state Fix permission card flash using PermissionsRequestState enum Jun 28, 2026
@gsbernstein gsbernstein marked this pull request as ready for review June 28, 2026 18:21
@gsbernstein gsbernstein requested a review from Copilot June 28, 2026 18:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a UI flash on cold start where the “HealthKit Access Required” card appeared briefly for users who already granted permissions, by introducing an explicit authorization UI state machine.

Changes:

  • Added a PermissionsRequestState enum to represent .loading, .shouldRequest, and .hasRequested states for the read-authorization flow.
  • Replaced the previous boolean authorization flag with the new state enum in HealthKitManager.
  • Updated ContentView to switch between a ProgressView, the authorization card, and the main content based on permissionsRequestState.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
Bedtime/Bedtime/Models/HealthKitManager.swift Introduces PermissionsRequestState and updates authorization/fetch logic to drive UI state explicitly.
Bedtime/Bedtime/ContentView.swift Switches authorization UI rendering from a boolean flag to the new state enum, including a loading indicator.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 80 to 88
func fetchSleepData() async throws {
defer {
if permissionsRequestState == .loading {
permissionsRequestState = .shouldRequest
}
}
try await requestAuthorization()
try await loadSleepData()
}
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.

3 participants