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.

Table of Contents

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

Option Type Required Description
publicKey String Yes Your Hyphen API public key.
application String Yes The application id or alternate id.
environment String Yes The environment identifier for the Hyphen project (project environment ID or alternateId).
horizonUrls [String] No Custom Hyphen Horizon URLs for fetching flags.
enableToggleUsage Bool No Enable/disable telemetry (default: true).

Network Configuration

Property Type Default Description
useCellularAccess Bool true Allow cellular network usage.
timeout Number 10 Request timeout in seconds.
maxRetries Number 3 Maximum retry attempts.
retryDelay Number 3 Delay between retries in seconds.
cacheExpiration Number 900 Cache TTL in seconds.

Evaluation Context

Field Type Required Description
targetingKey String Yes Unique identifier used for caching and targeting.
CustomAttributes [String: Value] No Custom attributes for targeting rules.
User Structure No User information including Email, Name, Id.
User.CustomAttributes [String: Value] No User-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()
        }
    }
}