Flags & @PipeFlag

Flags are remotely controllable variables that you can change from the PipeKit dashboard without shipping an app update. Think of them as feature flags with real-time push delivery.

What is a Flag?

A flag is a typed Swift property annotated with @PipeFlag that registers itself with PipeKit at app launch. The property works exactly like a normal variable, but its value can be overridden remotely from the dashboard in real-time.

Flags are safe by design. They only accept values that match the declared type. If the PipeKit server is unreachable, the compiled default value is used. Your app always works, with or without a connection.

Declaring a Flag

Use the @PipeFlag macro on a stored property with a default value. Supported types are Bool, Int, Double, and String.

AppFlags.swift
import PipeKitSDK
class AppFlags {
@PipeFlag var isMaintenanceMode = false
@PipeFlag var maxRetries = 3
@PipeFlag var refreshInterval = 30.0
@PipeFlag var welcomeMessage = "Hello!"
}

Custom Display Names

By default, the property name is used as the flag identifier in the dashboard. You can provide a custom display name for better readability.

NetworkFlags.swift
@PipeFlag("api-endpoint")
var apiEndpoint = "https://api.prod.com/v2"
@PipeFlag("cdn-url")
var cdnBaseURL = "https://cdn.pipekit.dev"

How It Works

The @PipeFlag macro transforms your stored property into a computed property backed by PipeKit's FlagStore. Here's the lifecycle:

1

Registration

On app launch, the SDK reports all @PipeFlag properties to the PipeKit server with their names, types, and default values.

2

Sync

The server responds with any active overrides. These are applied to the local FlagStore immediately.

3

Real-time Push

When you change a flag value in the dashboard, the override is pushed to connected devices via WebSocket instantly.

4

Value Resolution

When your code reads the property, the FlagStore resolves the value using a priority chain: remote override > local override > compiled default.

Value Resolution Priority

When your code reads a flag property, the value is resolved in this order:

1.
Remote overrideSet by an admin from the dashboard. Pushed via WebSocket or pulled via HTTP sync.
2.
Local overrideSet programmatically via the property setter. Useful for testing.
3.
Compiled defaultThe value in your source code. Always used as the fallback.

Using Flags in Code

Read and write flags just like normal properties. No async, no callbacks, no special APIs.

MaintenanceCheck.swift
let flags = AppFlags()
// Reading — returns the current effective value
if flags.isMaintenanceMode {
showMaintenanceBanner()
}
// Writing — sets a local override (does not push to server)
flags.maxRetries = 5

Device Targeting

Flag overrides can target all devices or specific devices. This is useful for gradual rollouts, A/B testing, or debugging a specific user's device.

Global Override

Applies to all connected devices. Set from the dashboard by choosing "All Devices" when pushing an override.

Device-Specific Override

Applies only to selected devices. Choose "Specific Devices" in the dashboard and pick the target devices from the list.

Managing Flags in the Dashboard

The Flags page in the dashboard shows all registered flags for your app. For each flag you can see:

  • Flag name and identifier
  • Type badge (Bool, Int, Double, String)
  • Compiled default value
  • Current override value (if any)
  • Device targeting status
  • Last reported timestamp

Click the edit icon to push an override, or the trash icon to remove it. When you remove an override, all devices revert to the compiled default. Changes are pushed in real-time via WebSocket.

Supported Types

Bool

true / false

Int

0, 42, -1

Double

3.14, 0.5

String

"hello"

Best Practices

Always provide a sensible default

Your app should work perfectly with just the compiled defaults. Remote overrides are enhancements, not requirements.

Use Bool flags for kill switches

A @PipeFlag var isMaintenanceMode = false gives you an instant kill switch from the dashboard.

Group related flags

Keep flags in dedicated classes (e.g., AppFlags, NetworkFlags) for better organization.

Don't use flags for secrets

Flag values are visible in the dashboard and transmitted over the network. Use them for configuration, not credentials.

Next: Session Recording

Record and replay user sessions to debug issues in production.