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
Typed accessors
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:
.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 againstGET /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
: keepalivecomment 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:@Sendable and is invoked off the main thread — hop to the main actor before touching UI state. Pass nil to remove the handler:
validateAttestation(). If the stream is unavailable, reads still work — they just fall back to the cache TTL.