Swift

Hyphen Toggle Provider for Swift is an OpenFeature provider implementation that enables seamless feature flag evaluation in iOS and macOS applications. This provider integrates Hyphen's feature flagging system with the OpenFeature SDK, providing robust feature management with minimal setup.

Installation

Add the package using Swift Package Manager. Either through Xcode's UI (File > Swift Packages > Add Package Dependency) or by adding this line to your Package.swift:

.package(url: "https://github.com/hyphen/hyphen-openfeature-swift", from: "0.2.0")

Select the Toggle target during installation.

You'll also need the OpenFeature Swift SDK:

.package(url: "https://github.com/open-feature/swift-sdk", from: "0.1.0")

Setup and Initialization

To integrate the Hyphen Toggle provider into your application, follow these steps:

  1. Configure the provider with your publicKey, application and environment.
    You can specify the environment in one of two formats:

    • Alternate ID (e.g., "production", "staging") — the environment in which your application is running.
    • Project Environment ID (e.g., pevr_abc123) — useful for internal references.
  2. Register the provider with OpenFeature.

import Toggle
import OpenFeature

let configuration = HyphenConfiguration(
    using: "your-public-key",
    application: "your-app-name",
    environment: "development" // or project environment ID
)

let provider = HyphenProvider(using: configuration)
await OpenFeatureAPI.shared.setProviderAndWait(provider: provider)
  1. Create an evaluation context for feature targeting evaluations, incorporating user or application context.
let context = hyphenEvaluationContext(
    targetingKey: "user-123",
    values: [
        "CustomAttributes": .structure([
            "plan": .string("premium"),
            "betaAccess": .boolean(true)
        ]),
        "User": .structure([
            "Email": .string("[email protected]"),
            "Name": .string("User Name"),
            "CustomAttributes": .structure([
                "subscription": .string("pro")
            ])
        ])
    ]
)

await OpenFeatureAPI.shared.setProviderAndWait(
    provider: provider,
    initialContext: context
)

Usage

Basic Flag Evaluation

let client = OpenFeatureAPI.shared.getClient()

// Boolean flag
let boolFlag = client.getBooleanValue(key: "my-bool-flag", defaultValue: false)

// String flag
let stringFlag = client.getStringValue(key: "my-string-flag", defaultValue: "default")

// Number flag
let numberFlag = client.getIntegerValue(key: "my-number-flag", defaultValue: 0)

Getting Flag Details

For more detailed information about flag evaluations:

let client = OpenFeatureAPI.shared.getClient()
let flagDetails: FlagEvaluationDetails<Bool> = client.getDetails(
    key: "my-feature-flag",
    defaultValue: false
)

print("Value: \(flagDetails.value)")
print("Variant: \(flagDetails.variant ?? "unknown")")
print("Reason: \(flagDetails.reason ?? "unknown")")

Configuration

Provider Options

OptionTypeRequiredDescription
publicKeyStringYesYour Hyphen API public key.
applicationStringYesThe application id or alternate id.
environmentStringYesThe environment identifier for the Hyphen project (project environment ID or alternateId).
horizonUrls[String]NoCustom Hyphen Horizon URLs for fetching flags.
enableToggleUsageBoolNoEnable/disable telemetry (default: true).

Network Configuration

PropertyTypeDefaultDescription
useCellularAccessBooltrueAllow cellular network usage.
timeoutNumber10Request timeout in seconds.
maxRetriesNumber3Maximum retry attempts.
retryDelayNumber3Delay between retries in seconds.
cacheExpirationNumber900Cache TTL in seconds.

Evaluation Context

FieldTypeRequiredDescription
targetingKeyStringYesUnique identifier used for caching and targeting.
CustomAttributes[String: Value]NoCustom attributes for targeting rules.
UserStructureNoUser information including Email, Name, Id.
User.CustomAttributes[String: Value]NoUser-level custom properties.

Example

import Toggle
import OpenFeature

@main
struct MyApp: App {
    init() {
        Task {
            await setupFeatureFlags()
        }
    }

    func setupFeatureFlags() async {
        // Initialize the provider
        let configuration = HyphenConfiguration(
            using: "your-public-key",
            application: "your-app-name",
            environment: "development"
        )

        let provider = HyphenProvider(using: configuration)

        // Create evaluation context
        let context = hyphenEvaluationContext(
            targetingKey: "user-123",
            values: [
                "CustomAttributes": .structure([
                    "plan": .string("premium"),
                    "betaAccess": .boolean(true)
                ]),
                "User": .structure([
                    "Email": .string("[email protected]"),
                    "Name": .string("John Doe")
                ])
            ]
        )

        // Set provider with context
        await OpenFeatureAPI.shared.setProviderAndWait(
            provider: provider,
            initialContext: context
        )

        // Evaluate flags
        let client = OpenFeatureAPI.shared.getClient()

        let showNewFeature = client.getBooleanValue(
            key: "new-feature-enabled",
            defaultValue: false
        )

        let theme = client.getStringValue(
            key: "app-theme",
            defaultValue: "light"
        )

        print("New Feature Enabled: \(showNewFeature)")
        print("App Theme: \(theme)")
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}