Configuration
Learn how to configure the Toggly iOS SDK for different use cases.
TogglyConfig
The TogglyConfig struct contains all configuration options for the SDK.
import TogglyCore
let config = TogglyConfig(
appKey: "your-app-key",
environment: "Production",
baseURI: "https://definitions.toggly.io",
identity: "user-123",
featureDefaults: ["feature-a": true, "feature-b": false],
showFeatureDuringEvaluation: false,
refreshInterval: 180,
useSignedDefinitions: false,
connectTimeout: 10,
requestTimeout: 30,
storage: UserDefaultsStorage()
)
Initial groups and claims
Supply known context before initialization so the first evaluated request has the intended user, memberships and rule attributes:
let service = TogglyService(config: TogglyConfig(
appKey: "your-app-key",
identity: "user-123", // Stable user identifier.
groups: ["beta"], // Memberships used by targeting rules.
claims: ["plan": "pro"] // String rule attributes.
))
await service.initialize()
Empty groups/claims add no memberships/attributes. Omitted identity retains the stored/generated device ID; explicit empty identity stays empty. Context is copied at construction. Blank groups and empty claim names/values are omitted, with at most 20 claims sent in deterministic order. Use separate group entries, not commas inside group names. Per-check entity context is separate from this user targeting.
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
appKey | String? | nil | Your Toggly.io application key |
environment | String | "Production" | Environment name (e.g., "Staging", "Development") |
baseURI | String | "https://definitions.toggly.io" | API endpoint URL |
identity | String? | nil | User identifier for feature targeting |
featureDefaults | FeatureFlags | [:] | Default feature flag values |
showFeatureDuringEvaluation | Bool | false | Show content during initial loading |
refreshInterval | TimeInterval | 180 | Auto-refresh interval in seconds (0 to disable) |
useSignedDefinitions | Bool | false | Use signed definitions for enhanced security |
connectTimeout | TimeInterval | 10 | Connection timeout in seconds |
requestTimeout | TimeInterval | 30 | Request timeout in seconds |
storage | TogglyStorage? | nil | Custom storage implementation |
Environments
Configure different environments for development, staging, and production:
#if DEBUG
let config = TogglyConfig(
appKey: "dev-app-key",
environment: "Development",
refreshInterval: 30 // More frequent refreshes in dev
)
#else
let config = TogglyConfig(
appKey: "prod-app-key",
environment: "Production",
refreshInterval: 180
)
#endif
Feature Defaults
Provide default values for offline scenarios or faster initial rendering:
let config = TogglyConfig(
appKey: "your-app-key",
featureDefaults: [
"new-dashboard": false, // Disabled by default
"dark-mode": true, // Enabled by default
"experimental": false,
"maintenance-banner": false
]
)
These defaults are used when:
- The SDK hasn't initialized yet
- The device is offline
- A specific feature key doesn't exist on the server
Storage Options
Memory Storage (Default)
Data is stored in memory and lost when the app terminates:
let config = TogglyConfig(
appKey: "your-app-key",
storage: nil // Uses MemoryStorage by default
)
UserDefaults Storage
Persists data across app launches:
import TogglyCore
let config = TogglyConfig(
appKey: "your-app-key",
storage: UserDefaultsStorage()
)
With custom UserDefaults suite:
let customDefaults = UserDefaults(suiteName: "group.com.myapp.shared")!
let config = TogglyConfig(
appKey: "your-app-key",
storage: UserDefaultsStorage(defaults: customDefaults, keyPrefix: "toggly_")
)
Custom Storage
Implement the TogglyStorage protocol for custom storage:
import TogglyCore
actor KeychainStorage: TogglyStorage {
func get(_ key: String) async -> String? {
// Read from Keychain
}
func set(_ key: String, value: String) async {
// Write to Keychain
}
func delete(_ key: String) async {
// Delete from Keychain
}
func clear() async {
// Clear all Toggly keys from Keychain
}
}
let config = TogglyConfig(
appKey: "your-app-key",
storage: KeychainStorage()
)
Initialization
Shared Instance
Use the shared instance for most apps:
import TogglyCore
// Configure once at app startup
Toggly.configure(config: TogglyConfig(
appKey: "your-app-key",
environment: "Production"
))
// Initialize (async)
Task {
await Toggly.shared.initialize()
}
Custom Instance
Create separate instances for different use cases:
let analyticsService = TogglyService(config: TogglyConfig(
appKey: "analytics-key",
environment: "Production"
))
let experimentService = TogglyService(config: TogglyConfig(
appKey: "experiment-key",
environment: "Production"
))
Task {
await analyticsService.initialize()
await experimentService.initialize()
}
Refresh Configuration
Automatic Refresh
Configure automatic background refresh:
let config = TogglyConfig(
appKey: "your-app-key",
refreshInterval: 60 // Refresh every 60 seconds
)
Set to 0 to disable automatic refresh:
let config = TogglyConfig(
appKey: "your-app-key",
refreshInterval: 0 // Manual refresh only
)
Manual Refresh
Trigger a manual refresh:
Task {
let response = await Toggly.shared.refresh()
print("Refreshed: \(response.status)")
}
Timeouts
Configure network timeouts:
let config = TogglyConfig(
appKey: "your-app-key",
connectTimeout: 5, // 5 seconds to establish connection
requestTimeout: 15 // 15 seconds for entire request
)
Signed Definitions
Enable signed definitions for enhanced security:
let config = TogglyConfig(
appKey: "your-app-key",
useSignedDefinitions: true
)
Signed definitions require additional server-side configuration. Contact Toggly support for setup.
Local-Only Mode
Use the SDK without connecting to Toggly.io:
let config = TogglyConfig(
featureDefaults: [
"feature-a": true,
"feature-b": false,
"feature-c": true
]
)
Toggly.configure(config: config)
await Toggly.shared.initialize()
// All evaluations use the defaults
let isEnabled = await Toggly.shared.isFeatureOn("feature-a") // true
App Lifecycle Integration
UIKit (AppDelegate)
import UIKit
import TogglyCore
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
Toggly.configure(config: TogglyConfig(
appKey: "your-app-key",
environment: "Production"
))
Task {
await Toggly.shared.initialize()
}
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
Task {
await Toggly.shared.setAppState(.active)
}
}
func applicationDidEnterBackground(_ application: UIApplication) {
Task {
await Toggly.shared.setAppState(.background)
}
}
}
SwiftUI (App)
import SwiftUI
import TogglyCore
@main
struct MyApp: App {
@Environment(\.scenePhase) private var scenePhase
init() {
Toggly.configure(config: TogglyConfig(
appKey: "your-app-key",
environment: "Production"
))
Task {
await Toggly.shared.initialize()
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { _, newPhase in
Task {
switch newPhase {
case .active:
await Toggly.shared.setAppState(.active)
case .inactive:
await Toggly.shared.setAppState(.inactive)
case .background:
await Toggly.shared.setAppState(.background)
@unknown default:
break
}
}
}
}
}
Environment Variables
Store configuration in environment variables:
let appKey = ProcessInfo.processInfo.environment["TOGGLY_APP_KEY"] ?? ""
let environment = ProcessInfo.processInfo.environment["TOGGLY_ENVIRONMENT"] ?? "Production"
let config = TogglyConfig(
appKey: appKey,
environment: environment
)
Debug Information
Get debug info about the SDK state:
Task {
let debugInfo = await Toggly.shared.getDebugInfo()
print("Identity: \(debugInfo.identity ?? "none")")
print("App Key: \(debugInfo.appKey ?? "none")")
print("Environment: \(debugInfo.environment)")
print("Last Synced: \(debugInfo.lastSynced?.description ?? "never")")
print("Last Error: \(debugInfo.lastError ?? "none")")
print("Network: \(debugInfo.networkState?.isConnected == true ? "online" : "offline")")
print("App State: \(debugInfo.appState)")
}