App Lifecycle
Wire up foreground/background signals so the SDK can manage polling and background work.
The Rovenue SDK drives its polling and background work from two lifecycle signals you provide: setForeground(bool) and shutdown(). Without them, the SDK cannot know when to refresh entitlements, flush queued events, or stop background work gracefully.
Session events (app open, background, close) are recorded automatically once you wire up setForeground — you do not need to emit them manually.
Types on this page
These are void methods with no return value. Full definitions: Methods reference → Lifecycle.
| Method | Signature (RN) | Effect |
|---|---|---|
setForeground | setForeground(active: boolean) | true starts periodic entitlement and credit refreshes; false pauses polling to save battery and network |
shutdown | shutdown() | Stops all background work — polling, outbox flushing, and the change stream. Drains queued events synchronously before returning. |
Wire foreground/background signals
Call setForeground(true) when the app becomes active and setForeground(false) when it goes to the background. The SDK uses this to start and pause its internal polling loop.
import { useEffect } from 'react';
import { AppState } from 'react-native';
import { Rovenue } from '@rovenue/react-native-sdk';
useEffect(() => {
// Signal foreground immediately on mount
Rovenue.setForeground(true);
// Keep the SDK in sync as the app moves between states
const sub = AppState.addEventListener('change', (state) => {
Rovenue.setForeground(state === 'active');
});
return () => {
sub.remove();
Rovenue.shutdown();
};
}, []);Place this effect at the root of your app (e.g. in App.tsx) so it runs for the full app lifetime.
// AppDelegate.swift
import Rovenue
func applicationDidBecomeActive(_ application: UIApplication) {
Rovenue.shared.setForeground(true)
}
func applicationDidEnterBackground(_ application: UIApplication) {
Rovenue.shared.setForeground(false)
}
func applicationWillTerminate(_ application: UIApplication) {
Rovenue.shared.shutdown()
}SceneDelegate / SwiftUI: wire the same calls to sceneDidBecomeActive, sceneDidEnterBackground, and sceneWillDeactivate, or use the .scenePhase environment value:
// SwiftUI — in App.swift
import SwiftUI
import Rovenue
@main
struct MyApp: App {
@Environment(\.scenePhase) private var phase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: phase) { newPhase in
Rovenue.shared.setForeground(newPhase == .active)
if newPhase == .background {
// setForeground(false) already called above; shutdown on terminate only
}
}
}
}// Application.kt — use ProcessLifecycleOwner for app-wide signals
import android.app.Application
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import dev.rovenue.sdk.Rovenue
class App : Application() {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(
object : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// App moved to foreground
Rovenue.shared.setForeground(true)
}
override fun onStop(owner: LifecycleOwner) {
// App moved to background
Rovenue.shared.setForeground(false)
}
}
)
}
override fun onTerminate() {
Rovenue.shared.shutdown()
super.onTerminate()
}
}Register App in AndroidManifest.xml:
<application
android:name=".App"
... >Call shutdown on app termination
shutdown() stops all background work and drains any queued outbox events synchronously. Call it only when the process is ending — not on every background transition.
// Already handled in the useEffect cleanup above.
// If you need an explicit teardown (e.g. on logout):
await Rovenue.shutdown();// AppDelegate.swift — called by the OS before the process exits
func applicationWillTerminate(_ application: UIApplication) {
// Give the SDK time to drain queued events
let task = UIApplication.shared.beginBackgroundTask(withName: "RovenueDrain")
Rovenue.shared.shutdown()
UIApplication.shared.endBackgroundTask(task)
}// Application.onTerminate is only called in emulators.
// For production, tie shutdown to ProcessLifecycleOwner.onDestroy or
// handle it in your Activity's onDestroy if you have a single-activity app:
override fun onDestroy() {
Rovenue.shared.shutdown()
super.onDestroy()
}shutdown() drains any queued outbox events synchronously before returning. On iOS, requesting a short background-task window (via beginBackgroundTask) gives the SDK extra time to flush events that were queued just before termination, improving delivery reliability.
Calling shutdown() also cancels the SDK's internal coroutine scope (Kotlin) and Task (Swift). Any change-stream collectors running inside those scopes will stop. See Reacting to changes for correct collector wiring.