Skip to main content
Feature flags let you control feature rollout from the Grantiva dashboard without app updates. Access them via grantiva.flags. FlagService is an actor, so every member is reached with await.
Flag endpoints require authentication: run validateAttestation() once before reading flags (the SDK then attaches the attestation JWT automatically). In the Simulator, initialize the SDK with an API key — see Simulator Setup. Requests without either receive a 401.

Get all flags

Flags are cached in memory for 5 minutes. See Cache control.

Typed accessors

Default values are returned when the flag doesn’t exist or can’t be parsed to the requested type.

Get a single flag

Environments

Flags can hold a different value per environment. FlagEnvironment has three cases — .development, .staging, and .production — and both flag reads and the live stream are scoped to the service’s current environment:
The SDK evaluates against .production. Use per-environment values in the dashboard to vary behaviour between your builds.
environment and cacheTTL are actor-isolated properties with no setter on the public API, so app code can read them but not change them. If you need staging evaluation or a different TTL on device, let us know.

Cache control

Flags are cached in memory for 5 minutes (cacheTTL, 300 seconds).
refresh() and clearCache() do the same thing today; clearCache() is what the SDK calls internally. The cache is cleared automatically when user identity changes via grantiva.identify(_:) or grantiva.clearIdentity(), and a live update from the stream replaces the cache in place.

Live updates (SSE)

The SDK can hold a Server-Sent Events stream open against GET /api/v1/flags/stream so flag changes propagate to devices in seconds instead of waiting for the cache TTL. A few behaviors worth knowing (SDK 2.0.6+):
  • The server emits a : keepalive comment every 20 seconds; the SDK’s idle timeout is 75 seconds (~3 missed keepalives), so dead connections are detected and reconnected without churning on healthy quiet streams.
  • Reconnect backoff resets after a healthy connection (60s+ uptime) drops, so devices on flaky networks don’t accumulate permanent delays.
  • The stream is scoped to the current environment.
  • On iOS the SDK closes the stream when the app backgrounds and reopens it on foreground. clearStoredData() stops it.

React to live updates

Register a handler to be told when the stream delivers new values:
The closure is @Sendable and is invoked off the main thread — hop to the main actor before touching UI state. Pass nil to remove the handler:
Streaming starts automatically after a successful validateAttestation(). If the stream is unavailable, reads still work — they just fall back to the cache TTL.

Tier limits