Type-safe feature flags with local defaults, remote overrides, and SwiftUI integration
.package(url: "https://github.com/philiprehberger/swift-feature-flags.git", from: "0.1.0")Type-safe feature flags with local defaults, remote overrides, and SwiftUI integration
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/philiprehberger/swift-feature-flags.git", from: "0.1.0")
]
Then add "FeatureFlags" to your target dependencies:
.target(name: "YourTarget", dependencies: [
.product(name: "FeatureFlags", package: "swift-feature-flags")
])
import FeatureFlags
// Define flags with defaults
let registry = FlagRegistry()
await registry.register([
LocalProvider(flags: [
"dark_mode": true,
"max_items": 50,
"welcome_message": "Hello!"
])
])
// Check flags
let darkMode = await registry.isEnabled("dark_mode") // => true
let maxItems: Int = await registry.value(for: "max_items", default: 10) // => 50
struct AppFlags {
@Flag("dark_mode", default: false) var darkMode
@Flag("max_items", default: 10) var maxItems
@Flag("welcome_message", default: "Hi") var welcomeMessage
}
let remote = RemoteProvider(url: URL(string: "https://api.example.com/flags.json")!)
await registry.register([
LocalProvider(flags: ["dark_mode": false]), // default
remote // overrides local when available
])
await try registry.refresh() // fetch remote flags
let test = ABTest(key: "onboarding_flow", variants: ["control", "variant_a", "variant_b"])
let variant = test.variant(for: userId) // deterministic per user
await registry.override("dark_mode", value: true) // force-enable for debugging
await registry.clearOverrides()
| Method | Description |
|---|---|
register(_:) | Register flag providers in priority order |
value(for:default:) | Get a typed flag value with fallback |
isEnabled(_:) | Check if a boolean flag is true |
refresh() | Refresh all remote providers |
override(_:value:) | Override a flag locally for debugging |
clearOverrides() | Clear all manual overrides |
| Method | Description |
|---|---|
value(for:) | Return a flag value or nil |
refresh() | Refresh flag data from source |
| Method | Description |
|---|---|
variant(for:) | Deterministic variant for a user ID |
swift build
swift test
💬 Bluesky · 🐦 X · 💼 LinkedIn · 🌐 Website · 📦 GitHub · ☕ Buy Me a Coffee · ❤️ GitHub Sponsors