Skip to content

Add lifecycle callbacks for iOS and tvOS - #1390

Open
olipetrovic wants to merge 1 commit into
supabase-community:masterfrom
olipetrovic:fix/apple-lifecycle-callbacks
Open

Add lifecycle callbacks for iOS and tvOS#1390
olipetrovic wants to merge 1 commit into
supabase-community:masterfrom
olipetrovic:fix/apple-lifecycle-callbacks

Conversation

@olipetrovic

Copy link
Copy Markdown

Add lifecycle callbacks for iOS and tvOS

iOS and tvOS suspend the process while the app is in the background, which freezes the delay-based auto-refresh timer. Without lifecycle callbacks the timer can sleep through the access token's expiry, leaving every request with an expired JWT (PostgREST 401 PGRST303) after the app returns to the foreground - until the user signs out and back in. Hit this in production: the edge logs for the incident show a burst of 401s on every data request and not a single grant_type=refresh_token call.

What this does

Mirrors the Android implementation via NSNotificationCenter:

  • On UIApplicationDidEnterBackgroundNotification: cancel auto refresh and set the status to Initializing, as Android's onStop does.
  • On UIApplicationWillEnterForegroundNotification: re-load the session from storage, which runs the existing threshold check - refreshing immediately if the token went stale while suspended, or re-arming the timer with the correct remaining time if not.

Gated behind the existing enableLifecycleCallbacks config flag (its doc now says Android, iOS and tvOS).

Structure

The appleMain setupPlatform actual now delegates to a per-family setupApplePlatform expect:

  • a new uikit intermediate source set (iOS + tvOS, added to the hierarchy in Auth/build.gradle.kts) holds the observer registration;
  • macOS keeps the previous initDone()-only behavior - processes are not suspended there, so the timer keeps running;
  • watchOS also keeps the previous behavior for now - it does suspend apps, but its lifecycle notifications live in WatchKit (WKApplication), not UIKit, so it would need its own implementation.

Notes

  • No behavior change when enableLifecycleCallbacks = false.
  • Verified: :auth-kt:compileKotlinIosArm64, compileKotlinIosSimulatorArm64, compileKotlinTvosArm64, compileKotlinWatchosArm64, compileKotlinMacosArm64, compileKotlinJvm, allMetadataJar.

iOS and tvOS suspend the process while the app is in the background,
which freezes the delay-based auto-refresh timer. Without lifecycle
callbacks the timer can sleep through the access token's expiry, leaving
every request with an expired JWT (PostgREST 401 PGRST303) after the app
returns to the foreground - until the user signs out and back in.

Mirror the Android implementation via NSNotificationCenter: cancel auto
refresh on UIApplicationDidEnterBackgroundNotification, and re-import
the session from storage on UIApplicationWillEnterForegroundNotification
- refreshing immediately if the token went stale while suspended, or
re-arming the timer with the correct remaining time if not. Gated behind
the existing enableLifecycleCallbacks config flag.

The appleMain setupPlatform actual now delegates to a per-family
setupApplePlatform expect: a new uikit source set (iOS + tvOS) holds the
observer registration, while macOS (processes are not suspended) and
watchOS (lifecycle notifications live in WatchKit, not UIKit) keep the
previous initDone-only behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant