Rovenue SDK
Guides

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.

MethodSignature (RN)Effect
setForegroundsetForeground(active: boolean)true starts periodic entitlement and credit refreshes; false pauses polling to save battery and network
shutdownshutdown()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.

On this page