### Basic Event Handling Setup Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Demonstrates setting up handlers for common paywall events like open, close, dismiss, and purchase succeeded. This setup is then used when presenting a paywall. ```swift let handlers = PaywallEventHandlers() .onOpen { print("Paywall opened: \(event.paywallName)") } .onClose { print("Paywall closed") } .onDismissed { print("User dismissed") } .onPurchaseSucceeded { print("Purchase: \(event.productId)") } Helium.shared.presentPaywall( trigger: "premium_upgrade", eventHandlers: handlers, onPaywallNotShown: { print("Not shown: \(reason)") } ) ``` -------------------------------- ### Enable External Web Checkout Example Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/types.md Example of how to enable external web checkout with specific URLs and payment processors. Use `.paddle` for Paddle only. ```swift .enableExternalWebCheckout( successURL: "myapp://success", cancelURL: "myapp://cancel", paymentProcessors: .paddle // Only Paddle ) ``` -------------------------------- ### Basic Purchase Testing Setup Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Sets up a mock purchase handler to simulate immediate success for testing. ```swift // Setup mock purchase Helium.testing.purchaseHandler = { productId in print("Mock purchase: \(productId)") return .purchased } // Now when user taps purchase button, it succeeds immediately Helium.shared.presentPaywall( trigger: "premium", onPaywallNotShown: { _ in } ) ``` -------------------------------- ### Test Restore Flow Setup Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Configures a mock restore handler to simulate a successful restore for testing purposes. ```swift Helium.testing.restoreHandler = { return true // Simulate successful restore } // User can tap restore button without real App Store call Helium.shared.presentPaywall( trigger: "restore", onPaywallNotShown: { _ in } ) ``` -------------------------------- ### Complete Test Environment Setup and Teardown Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Provides functions to set up and tear down the test environment by configuring mock handlers and resetting them afterwards. ```swift func setupTestEnvironment() { // Mock purchase Helium.testing.purchaseHandler = { productId in if productId.contains("free") { return .purchased } return .cancelled } // Mock restore Helium.testing.restoreHandler = { return true } // Mock intro offer Helium.testing.introOfferEligibility = { productId in return productId.contains("trial") } } func teardownTestEnvironment() { Helium.testing.reset() } // In test func testPremiumPurchase() { setupTestEnvironment() defer { teardownTestEnvironment() } // Test purchase flow testPaywallFlow() } ``` -------------------------------- ### Development Setup for Helium Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Configure debug logging, add a log listener, and set up a mock purchase handler for testing during development builds. ```swift // Debug logging Helium.config.logLevel = .debug // Add log listener let logToken = HeliumLogger.addLogListener { event in os_log("Helium: %®", log: .default, type: .debug, event.message) } // Mock purchases for testing #if DEBUG Helium.testing.purchaseHandler = { productId in return .purchased } #endif Helium.shared.initialize(apiKey: testApiKey) ``` -------------------------------- ### Test Intro Offer Eligibility Setup Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Sets up a mock intro offer eligibility handler before initializing Helium to control which products show intro offers. ```swift // Set before initialize Helium.testing.introOfferEligibility = { productId in // Only show intro for specific products return ["monthly_trial", "annual_trial"].contains(productId) } Helium.shared.initialize(apiKey: "sk_live_...") // Paywall will show intro offer UI for eligible products ``` -------------------------------- ### Production Setup for Helium Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Configure user identification, logging level, purchase delegate, and enable web checkout before initializing Helium for production. ```swift // Configure before init Helium.identify.userId = getUserId() Helium.identify.setUserTraits(getUserTraits()) Helium.config.logLevel = .error Helium.config.purchaseDelegate = StoreKitDelegate() // Enable web checkout Helium.config.enableExternalWebCheckout( successURL: "https://myapp.com/checkout/success", cancelURL: "https://myapp.com/checkout/cancel" ) Helium.shared.initialize(apiKey: productionApiKey) ``` -------------------------------- ### all Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Gets all experiment info for the user, including both predicted and active enrollments. Returns an array of all ExperimentInfo, or nil if the SDK is not initialized. ```APIDOC ## all() ### Description Gets all experiment info for user (both predicted and active enrollments). ### Method `public func all() -> [ExperimentInfo]?` ### Parameters None ### Response #### Success Response - **[ExperimentInfo]?** - Array of all `ExperimentInfo` (predicted + active), or `nil` if SDK not initialized. ### Request Example ```swift if let allExperiments = Helium.experiments.all() { for experiment in allExperiments { switch experiment.enrollmentStatus { case .activeEnrollment: print("Active enrollment at \(experiment.enrolledAt?.description ?? \"unknown\")") case .predictedEnrollment: print("Will be enrolled when trigger is hit") default: print("Unknown status") } } } ``` ``` -------------------------------- ### Handle Paywall Events with Experiment Info Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md This example shows how to use event handlers to access experiment information when a paywall is opened. It logs the experiment name and variant index. ```swift let handlers = PaywallEventHandlers() .onOpen { if let expInfo = event.getEventExperimentInfo() { print("Paywall in experiment: \(expInfo.experimentName ?? "unnamed")") print("Variant index: \(expInfo.chosenVariantDetails?.allocationIndex ?? 0)") } } Helium.shared.presentPaywall( trigger: "premium_upgrade", eventHandlers: handlers, onPaywallNotShown: { _ in } ) ``` -------------------------------- ### PaywallSkippedEvent Example Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/events.md Handle cases where a paywall is skipped due to targeting holdout or existing entitlement. This example demonstrates casting the event to PaywallSkippedEvent and accessing its skipReason. ```swift if let skipEvent = event as? PaywallSkippedEvent { print("Paywall skipped: \(skipEvent.skipReason.rawValue)") } ``` -------------------------------- ### Custom Purchase Delegate Setup Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Demonstrates how to implement a custom purchase delegate by conforming to `HeliumPaywallDelegate` and assigning it to `Helium.config.purchaseDelegate`. This allows for custom logic in `makePurchase` and `restorePurchases`. ```swift class MyPurchaseDelegate: HeliumPaywallDelegate { var delegateType: String { "custom" } func makePurchase(productId: String) async -> HeliumPaywallTransactionStatus { // Custom purchase logic return .purchased } func restorePurchases() async -> Bool { return true } func onPaywallEvent(_ event: HeliumEvent) { // Log event if let openEvent = event as? PaywallOpenEvent { print("Paywall opened: \(openEvent.paywallName)") } } } Helium.config.purchaseDelegate = MyPurchaseDelegate() let handlers = PaywallEventHandlers() .onPurchaseSucceeded { print("Purchase from \(event.paymentProcessor.rawValue)") } ``` -------------------------------- ### PaywallOpenEvent Example Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/events.md Log details when a paywall is opened, including its name, view type, and loading time. This snippet demonstrates accessing properties of the PaywallOpenEvent. ```swift .onOpen { event in print("Paywall '\(event.paywallName)' opened") print("View type: \(event.viewType.rawValue)") print("Load time: \(event.loadTimeTakenMS ?? 0)ms") } ``` -------------------------------- ### PaywallCloseEvent Example Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/events.md Log a message when a paywall is closed. This is a simple handler for the PaywallCloseEvent. ```swift .onClose { event in print("Paywall closed") } ``` -------------------------------- ### Initialize Helium SDK on App Launch Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Initialize the Helium SDK when your application launches. Provide your live API key during initialization. This setup is typically done within the main App struct using the `.onAppear` modifier. ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() .onAppear { Helium.shared.initialize(apiKey: "sk_live_...") } } } } ``` -------------------------------- ### UI Test Setup with Mock Purchase Handler Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Configure Helium's testing module for UI tests by setting a mock purchase handler before launching the application. This allows simulating purchase flows during testing. ```swift // In XCUITest setup override func setUp() { super.setUp() let app = XCUIApplication() // Pass launch arguments to enable test mode app.launchArguments = ["ENABLE_TEST_MODE"] app.launch() // Configure test handlers Helium.testing.purchaseHandler = { _ in .purchased } } func testPaywallPurchase() { // Open paywall app.buttons["Show Paywall"].tap() // Tap purchase (will use mock) app.buttons["Subscribe"].tap() // Verify success screen XCTAssert(app.staticTexts["Purchase Successful"].exists) } ``` -------------------------------- ### Get All Experiment Information (Predicted and Active) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Retrieves all experiment information for the user, including both predicted and active enrollments. Returns nil if the SDK is not initialized. Useful for a comprehensive view of experiment status. ```swift public func all() -> [ExperimentInfo]? ``` ```swift if let allExperiments = Helium.experiments.all() { for experiment in allExperiments { switch experiment.enrollmentStatus { case .activeEnrollment: print("Active enrollment at \(experiment.enrolledAt?.description ?? "unknown")") case .predictedEnrollment: print("Will be enrolled when trigger is hit") default: print("Unknown status") } } } ``` -------------------------------- ### Get Subscription Status by Product ID Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Fetches the subscription status for a specific product ID. Returns `nil` if the status is not found. ```swift public func subscriptionStatusFor(productId: String) async -> Product.SubscriptionInfo.Status? ``` ```swift if let status = await Helium.entitlements.subscriptionStatusFor(productId: "monthly_plan") { print("Status: \(status)") } ``` -------------------------------- ### enrolled Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Gets all experiments the user is currently enrolled in. Returns an array of ExperimentInfo for active enrollments, or nil if the SDK is not initialized. ```APIDOC ## enrolled() ### Description Gets all experiments user is currently enrolled in. ### Method `public func enrolled() -> [ExperimentInfo]?` ### Parameters None ### Response #### Success Response - **[ExperimentInfo]?** - Array of `ExperimentInfo` for active enrollments, or `nil` if SDK not initialized. ### Criteria for inclusion: - User has hit the trigger and been allocated - Experiment is currently running ### Request Example ```swift if let activeExperiments = Helium.experiments.enrolled() { for experiment in activeExperiments { print("Active: \(experiment.trigger) - \(experiment.experimentName ?? \"unknown\")") print("Enrolled at: \(experiment.enrolledAt?.description ?? \"unknown\")") print("Variant: \(experiment.chosenVariantDetails?.allocationName ?? \"unknown\")") } } ``` ``` -------------------------------- ### Set User ID and Custom Traits Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Configure user identification properties before initializing the SDK. This ensures targeting and analytics are available from the start. ```swift Helium.identify.userId = "user-12345" Helium.identify.setUserTraits([ "plan": "premium", "cohort": "early_access" ]) ``` -------------------------------- ### Get Paywall Download Status Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Returns the current download status of the paywall configuration. Possible statuses include not downloaded, in progress, success, or failure. ```swift public func getDownloadStatus() -> HeliumFetchedConfigStatus ``` ```swift switch Helium.shared.getDownloadStatus() { case .downloadSuccess: print("Paywalls loaded") case .inProgress: print("Downloading...") case .downloadFailure: print("Download failed") default: break } ``` -------------------------------- ### Get All Currently Enrolled Experiments Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Fetches an array of all experiments the user is currently enrolled in. This includes experiments where the user has been allocated and the experiment is active. Returns nil if the SDK is not initialized. ```swift public func enrolled() -> [ExperimentInfo]? ``` ```swift if let activeExperiments = Helium.experiments.enrolled() { for experiment in activeExperiments { print("Active: \(experiment.trigger) - \(experiment.experimentName ?? "unknown")") print("Enrolled at: \(experiment.enrolledAt?.description ?? "unknown")") print("Variant: \(experiment.chosenVariantDetails?.allocationName ?? "unknown")") } } ``` -------------------------------- ### Basic Helium SDK Initialization Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumConfig.md Sets the log level and purchase delegate, then initializes the Helium SDK with an API key. Ensure to replace 'sk_live_...' with your actual API key. ```swift Helium.config.logLevel = .info Helium.config.purchaseDelegate = StoreKitDelegate() Helium.shared.initialize(apiKey: "sk_live_...") ``` -------------------------------- ### Get Paywall Metadata Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Retrieves metadata for a paywall configured for a specific trigger. Requires paywalls to be downloaded. ```swift public func getPaywallInfo(trigger: String) -> PaywallInfo? ``` ```swift if let info = Helium.shared.getPaywallInfo(trigger: "onboarding") { print("Template: \(info.paywallTemplateName), Should show: \(info.shouldShow)") } ``` -------------------------------- ### Mock Intro Offer Eligibility for Testing Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Simulate intro offer eligibility for specific product IDs during testing. This helps in testing subscription onboarding flows. ```swift Helium.testing.introOfferEligibility = { productId in return productId.contains("trial") } ``` -------------------------------- ### subscriptionStatusFor(productId:) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Gets the subscription status for a specific product ID. Returns the status if found, otherwise nil. ```APIDOC ## subscriptionStatusFor(productId:) ### Description Gets subscription status for a specific product. ### Method `async -> Product.SubscriptionInfo.Status?` ### Parameters #### Path Parameters - **productId** (String) - Required - The ID of the product to check. ### Returns Subscription status if found; `nil` otherwise. ### Example ```swift if let status = await Helium.entitlements.subscriptionStatusFor(productId: "monthly_plan") { print("Status: \(status)") } ``` ``` -------------------------------- ### Get Purchased Product IDs Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Retrieves all product IDs for which the user currently has access. Does not include consumable purchases. ```swift public func purchasedProductIds() async -> [String] ``` ```swift let products = await Helium.entitlements.purchasedProductIds() print("User has purchased: \(products)") ``` -------------------------------- ### Release Workflow Overview Source: https://github.com/cloudcaptainai/helium-swift/blob/main/CONTRIBUTING.md This diagram illustrates the sequence of events for creating a release, from pushing a new version to publishing a CocoaPod. ```text Release Overview: Push new version (BuildConstants.swift) to main â Release CI - Trigger Tests workflow â Tests run in helium-demo â Tests passed â Create Release workflow â Create CocoaPod workflow ``` -------------------------------- ### subscriptionStatusFor(subscriptionGroupID:) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Gets the subscription status for a given subscription group ID. Returns the status if found, otherwise nil. ```APIDOC ## subscriptionStatusFor(subscriptionGroupID:) ### Description Gets subscription status for a subscription group. ### Method `async -> Product.SubscriptionInfo.Status?` ### Parameters #### Path Parameters - **subscriptionGroupID** (String) - Required - The ID of the subscription group to check. ### Returns Subscription status if found; `nil` otherwise. ### Example ```swift if let status = await Helium.entitlements.subscriptionStatusFor(subscriptionGroupID: "premium") { print("Status: \(status)") } ``` ``` -------------------------------- ### Get All Active Experiments Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Retrieves a list of all experiments the user is currently enrolled in. It prints the count of active experiments and details for each. ```APIDOC ## Get All Active Experiments ### Description Retrieves a list of all experiments the user is currently enrolled in. It prints the count of active experiments and details for each. ### Method ```swift Helium.experiments.enrolled() ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift if let activeExperiments = Helium.experiments.enrolled() { print("Active experiments: \(activeExperiments.count)") for exp in activeExperiments { print("- \(exp.experimentName ?? "unnamed") (\(exp.experimentId ?? "no-id"))") } } ``` ### Response #### Success Response - `activeExperiments` (Array?): An array of experiments the user is enrolled in. - `exp.experimentName` (String?): The name of the experiment. - `exp.experimentId` (String?): The ID of the experiment. #### Response Example ``` Active experiments: 2 - New Feature Rollout (exp-123) - A/B Test (exp-456) ``` ``` -------------------------------- ### introOfferEligibility Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumTesting.md Stubbed intro-offer eligibility check for a product. When set, it overrides StoreKit's real eligibility check. It takes a product ID string and returns a boolean indicating eligibility. ```APIDOC ## introOfferEligibility ### Description Stubbed intro-offer eligibility check for a product. When set, it overrides StoreKit's real eligibility check. It takes a product ID string and returns a boolean indicating eligibility. ### Method Signature `public var introOfferEligibility: ((String) async -> Bool)?` ### Parameters * **productId** (String) - The ID of the product to check eligibility for. ### Returns * **Bool** - `true` if eligible for intro offer; `false` otherwise. ### Example ```swift Helium.testing.introOfferEligibility = { productId in // Always eligible for trial products return productId.contains("trial") } ``` ``` -------------------------------- ### Present Paywall with Event Handling Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/INDEX.md Use this pattern to present a paywall and define actions for purchase success or failure. Ensure you have defined the necessary event handlers. ```swift Helium.shared.presentPaywall( trigger: "premium", eventHandlers: PaywallEventHandlers() .onPurchaseSucceeded { event in unlockFeature() }, onPaywallNotShown: { reason in print("Not shown: \(reason)") } ) ``` -------------------------------- ### Helium.shared.initialize(apiKey:) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Initializes the Helium paywall system with your provided API key. This method should be called early in your application's lifecycle. It's safe to call multiple times, and subsequent calls will be ignored. For best results, configure `Helium.identify` and `Helium.config` before initialization. The method asynchronously downloads paywall configurations and preloads necessary assets. ```APIDOC ## initialize(apiKey:) ### Description Initializes the Helium paywall system. ### Method `public func initialize(apiKey: String)` ### Parameters #### Path Parameters - **apiKey** (String) - Required - Your Helium API key from https://app.tryhelium.com/profile ### Request Example ```swift Helium.identify.userId = "user-123" Helium.config.logLevel = .info Helium.shared.initialize(apiKey: "sk_live_abc123...") ``` ``` -------------------------------- ### Present a Paywall with Custom Configuration Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Use this method to display a full-screen paywall based on a configured trigger. You can customize presentation options, handle lifecycle events, and define callbacks for entitlement status and when the paywall cannot be shown. The paywall displays a loading state while assets are downloaded and handles various payment processors. ```swift Helium.shared.presentPaywall( trigger: "premium_upgrade", config: PaywallPresentationConfig(dontShowIfAlreadyEntitled: true), eventHandlers: PaywallEventHandlers() .onPurchaseSucceeded { event in print("Purchase succeeded for \(event.productId)") }, onEntitled: { print("User is entitled") }, onPaywallNotShown: { reason in print("Paywall not shown: \(reason)") } ) ``` -------------------------------- ### Get Subscription Status by Group ID Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Fetches the subscription status for a given subscription group ID. Returns `nil` if the status is not found. ```swift public func subscriptionStatusFor(subscriptionGroupID: String) async -> Product.SubscriptionInfo.Status? ``` ```swift if let status = await Helium.entitlements.subscriptionStatusFor(subscriptionGroupID: "premium") { print("Status: \(status)") } ``` -------------------------------- ### infoForTrigger Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Gets experiment allocation info for a specific trigger. Returns ExperimentInfo if the trigger has associated experiment data, otherwise returns nil. ```APIDOC ## infoForTrigger(_ trigger: String) ### Description Gets experiment allocation info for a specific trigger. ### Method `public func infoForTrigger(_ trigger: String) -> ExperimentInfo?` ### Parameters #### Path Parameters - **trigger** (String) - Required - Trigger name to query ### Response #### Success Response - **ExperimentInfo?** - `ExperimentInfo` if trigger has experiment data; `nil` otherwise. ### Request Example ```swift if let experimentInfo = Helium.experiments.infoForTrigger("onboarding") { print("Experiment: \(experimentInfo.experimentName ?? \"unknown\")") print("Variant: \(experimentInfo.chosenVariantDetails?.allocationIndex ?? 0)") } ``` ``` -------------------------------- ### Fluent Builder Pattern for Paywall Events Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Shows how to chain event handlers using the fluent builder pattern when presenting a paywall. This allows for concise configuration of multiple event callbacks. ```swift Helium.shared.presentPaywall( trigger: "premium", eventHandlers: PaywallEventHandlers() .onOpen { analytics.trackImpression(event.paywallName) } .onPurchaseSucceeded { unlockFeature(event.productId) updateUI() } .onDismissed { logDropoff(event.paywallName) }, onPaywallNotShown: { handlePaywallUnavailable() } ) ``` -------------------------------- ### Get Experiment Information Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/INDEX.md Retrieve information about an A/B experiment associated with a specific trigger. This helps in understanding user allocation to different variants. ```swift if let exp = Helium.experiments.infoForTrigger("trigger") { print("Variant: \(exp.chosenVariantDetails?.allocationName ?? "control")") } ``` -------------------------------- ### Enable Paywall Previews in Dev Builds Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Allow triple-tapping to preview paywalls in development builds. This is useful for rapid UI testing. ```swift Helium.config.paywallPreviewsAutoEnabledInDevBuilds = true ``` -------------------------------- ### PaywallDismissedEvent Example Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/events.md Log when a user explicitly dismisses a paywall, including whether all paywalls were dismissed. This snippet shows how to access the 'dismissAll' property of PaywallDismissedEvent. ```swift .onDismissed { event in print("User dismissed paywall") print("Dismiss all? \(event.dismissAll)") } ``` -------------------------------- ### Initialize Helium SDK Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Call this method as early as possible in your app's lifecycle to initialize the Helium paywall system. It's safe to call multiple times. Ensure Helium.identify and Helium.config are set beforehand for optimal results. This call asynchronously downloads paywall configurations and preloads assets. ```swift Helium.identify.userId = "user-123" Helium.config.logLevel = .info Helium.shared.initialize(apiKey: "sk_live_abc123...") ``` -------------------------------- ### Set Custom API Endpoint Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumConfig.md Specify a custom Helium API endpoint. This is typically only done when instructed by Helium, for example, to use a staging environment. ```swift Helium.config.customAPIEndpoint = "https://staging-api.helium.com" ``` -------------------------------- ### createPaddlePortalSession() async throws -> URL Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Creates a Paddle Customer Portal session for subscription management. Returns the portal session URL. ```APIDOC ## createPaddlePortalSession() async throws -> URL ### Description Creates a Paddle Customer Portal session, enabling users to manage their subscriptions. The method returns the URL for the portal session. ### Method N/A (Swift async method call) ### Endpoint N/A ### Parameters None ### Throws Error if session creation fails. ### Request Example ```swift let portalURL = try await Helium.shared.createPaddlePortalSession() await UIApplication.shared.open(portalURL) ``` ### Response - **URL** (URL) - The URL for the Paddle Customer Portal session. ``` -------------------------------- ### Initialization Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Initializes the Helium SDK with your API key. It's recommended to set user identity and traits before initialization. ```APIDOC ## Initialization ### Description Initializes the Helium SDK with your API key. It's recommended to set user identity and traits before initialization. ### Method Swift SDK Method ### Endpoint N/A (SDK Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift // Set identity before initialize Helium.identify.userId = "user-123" Helium.identify.setUserTraits(["plan": "premium"]) // Initialize SDK Helium.shared.initialize(apiKey: "sk_live_...") ``` ### Response #### Success Response SDK initialization is typically non-blocking and does not return a direct success/failure value in this call. Initialization status can be observed via delegates or events if configured. #### Response Example None ``` -------------------------------- ### Initialize Helium SDK Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/INDEX.md Initialize the Helium SDK with your API key and set the user ID. Ensure this is done before other SDK operations. ```swift Helium.identify.userId = "user-123" Helium.shared.initialize(apiKey: "sk_live_...") ``` -------------------------------- ### Configure Paywall Presentation Options Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Customize how a paywall is presented by overriding the default presenter, adding custom traits, skipping if entitled, or setting a specific loading budget. ```swift let config = PaywallPresentationConfig( presentFromViewController: customVC, // Override presenter customPaywallTraits: HeliumUserTraits([...]), // Extra traits for paywall dontShowIfAlreadyEntitled: true, // Skip if user owns product loadingBudget: 5.0 // Override timeout ) Helium.shared.presentPaywall( trigger: "premium", config: config, onPaywallNotShown: { _ in } ) ``` -------------------------------- ### Get Experiment Info for a Specific Trigger Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Retrieves allocation information for a given trigger. Use this to check if a user is enrolled in an experiment associated with a specific event or action. ```swift public func infoForTrigger(_ trigger: String) -> ExperimentInfo? ``` ```swift if let experimentInfo = Helium.experiments.infoForTrigger("onboarding") { print("Experiment: \(experimentInfo.experimentName ?? "unknown")") print("Variant: \(experimentInfo.chosenVariantDetails?.allocationIndex ?? 0)") } ``` -------------------------------- ### Create Paddle Portal Session Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Creates a Paddle Customer Portal session for subscription management. Returns the portal session URL. Throws an error if session creation fails. ```swift public func createPaddlePortalSession() async throws -> URL ``` ```swift let portalURL = try await Helium.shared.createPaddlePortalSession() await UIApplication.shared.open(portalURL) ``` -------------------------------- ### PaywallPresentationConfig Structure Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/types.md Configuration options for presenting a paywall. Use this to customize presentation behavior and traits. ```swift public struct PaywallPresentationConfig { var presentFromViewController: UIViewController? var customPaywallTraits: HeliumUserTraits? var dontShowIfAlreadyEntitled: Bool var loadingBudget: TimeInterval? } ``` -------------------------------- ### Get Active Subscriptions Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumEntitlements.md Retrieves a dictionary of all active auto-renewable subscriptions, mapping product IDs to their subscription information, including status. Useful for displaying subscription details to the user. ```swift public func activeSubscriptions() async -> [String: Product.SubscriptionInfo] ``` ```swift let subscriptions = await Helium.entitlements.activeSubscriptions() for (productId, subInfo) in subscriptions { print("Product: \(productId)") print("Status: \(subInfo.status)") } ``` -------------------------------- ### Check if Paywalls are Loaded Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Returns true if the paywall configuration has been successfully downloaded. ```swift public func paywallsLoaded() -> Bool ``` ```swift if Helium.shared.paywallsLoaded() { print("Paywalls ready") } ``` -------------------------------- ### Retain Event Listener Reference Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Ensure that event listener objects are retained to prevent them from being deallocated immediately. Store a strong reference to the listener object, for example, by assigning it to a property of your class. ```swift // ❌ Won't work—listener deallocated immediately Helium.shared.addHeliumEventListener(MyListener()) // ✓ Keep strong reference self.listener = MyListener() Helium.shared.addHeliumEventListener(self.listener) ``` -------------------------------- ### Enable External Web Checkout Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Configure the SDK to use external web-based payment processors like Stripe and Paddle. Define success and cancel URLs for redirect handling. The `.onOpenURL` modifier is crucial for processing these redirects. ```swift Helium.config.enableExternalWebCheckout( successURL: "myapp://checkout/success", cancelURL: "myapp://checkout/cancel", paymentProcessors: .all ) // Handle redirects .onOpenURL { url in Helium.shared.handleURL(url) } ``` -------------------------------- ### PaywallPresentationConfig Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/types.md Configuration options for presenting a paywall, including the view controller to present from, custom user traits, whether to skip if already entitled, and a loading budget. ```APIDOC ## Struct: PaywallPresentationConfig ### Description Configuration options for presenting a paywall. ### Fields: | Field | Type | Default | Description | |---|---|---|---| | presentFromViewController | UIViewController? | nil | View controller to present from (uses top VC if nil) | | customPaywallTraits | HeliumUserTraits? | nil | Custom traits sent to paywall (merged with user traits) | | dontShowIfAlreadyEntitled | Bool | false | Skip paywall if user already has entitlement | | loadingBudget | TimeInterval? | nil | Max seconds to show loading state; overrides `Helium.config.defaultLoadingBudget` | ``` -------------------------------- ### Get User Traits Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumIdentify.md Retrieves the current custom user traits as a dictionary. Note that numeric values set as Int may be returned as Double after app restart due to JSON serialization. ```swift let traits = Helium.identify.getUserTraits() if let plan = traits["plan"] as? String { print("User plan: \(plan)") } ``` -------------------------------- ### Initialize PaywallEventHandlers Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Creates an empty event handlers instance. You can then assign handlers to its properties. ```swift public init() ``` ```swift var handlers = PaywallEventHandlers() handlers.onOpen = { print("Open") } ``` -------------------------------- ### PaywallEventHandlers Methods Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Methods for initializing and configuring paywall event handlers using a fluent builder pattern. ```APIDOC ## PaywallEventHandlers Methods ### init() **Description:** Creates an empty event handlers instance. **Example:** ```swift var handlers = PaywallEventHandlers() handlers.onOpen = { print("Open") } ``` ### onOpen(_ handler: (PaywallOpenEvent) -> Void) **Description:** Builder method to set the open handler. **Returns:** Self for chaining. **Example:** ```swift PaywallEventHandlers() .onOpen { print("Opened") } .onClose { print("Closed") } ``` ### onClose(_ handler: (PaywallCloseEvent) -> Void) **Description:** Builder method to set the close handler. ### onDismissed(_ handler: (PaywallDismissedEvent) -> Void) **Description:** Builder method to set the dismissal handler. ``` -------------------------------- ### Mock Purchase Handler for Testing Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Implement a mock purchase handler to simulate purchase outcomes during testing. This allows for controlled testing of purchase flows. ```swift Helium.testing.purchaseHandler = { productId in return productId.contains("trial") ? .purchased : .cancelled } ``` -------------------------------- ### Set Default Loading Budget Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Define the maximum time in seconds the SDK will wait for loading resources before timing out. The default is 7.0 seconds. ```swift Helium.config.defaultLoadingBudget = 7.0 ``` -------------------------------- ### Handle Purchase Success Events Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Respond to successful purchases by updating your application's state, such as marking a user as premium. You can also log purchase conversions and display success UI elements. This is typically done using `PaywallEventHandlers` and the `.onPurchaseSucceeded` method. ```swift PaywallEventHandlers() .onPurchaseSucceeded { event in // Update app state UserDefaults.standard.set(true, forKey: "isPremium") // Log conversion Analytics.trackPurchase(event.productId) // Show success UI showSuccessMessage() } ``` -------------------------------- ### Define Paywall Event Handlers Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Set up callbacks for various paywall events, including opening, closing, dismissal, successful purchases, custom actions, and any event. ```swift let handlers = PaywallEventHandlers() .onOpen { event in print("Opened: \(event.paywallName)") } .onClose { event in print("Closed") } .onDismissed { event in print("Dismissed") } .onPurchaseSucceeded { event in print("Purchased: \(event.productId)") } .onCustomPaywallAction { event in print("Action: \(event.actionName)") } .onAnyEvent { event in print("Event: \(event.eventName)") } ``` -------------------------------- ### defaultLoadingBudget Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumConfig.md Configures the maximum time in seconds the SDK will display a loading state before showing a fallback. Setting to 0 or negative disables the loading state. ```APIDOC ## defaultLoadingBudget ### Description Configures the maximum time in seconds the SDK will display a loading state before showing a fallback. Setting to 0 or negative disables the loading state. ### Property `defaultLoadingBudget: TimeInterval` ### Default Value `7.0` seconds ### Note Per-presentation override is available via `PaywallPresentationConfig.loadingBudget`. ### Example ```swift Helium.config.defaultLoadingBudget = 5.0 // 5 second timeout ``` ``` -------------------------------- ### Presenting Paywalls (Full-screen Modal) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Presents a paywall as a full-screen modal. You can specify a trigger, event handlers for purchase outcomes, and a callback for when the paywall is not shown. ```APIDOC ## Presenting Paywalls (Full-screen Modal) ### Description Presents a paywall as a full-screen modal. You can specify a trigger, event handlers for purchase outcomes, and a callback for when the paywall is not shown. ### Method Swift SDK Method ### Endpoint N/A (SDK Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift // Full-screen modal Helium.shared.presentPaywall( trigger: "premium_upgrade", eventHandlers: PaywallEventHandlers() .onPurchaseSucceeded { event in unlockFeature() }, onPaywallNotShown: { reason in print("Paywall not shown: \(reason)") } ) ``` ### Response #### Success Response This method initiates the paywall presentation. Success is indicated by the paywall being displayed. Failure or reasons for not showing are handled by the `onPaywallNotShown` callback. #### Response Example None ``` -------------------------------- ### Mock Restore Handler for Testing Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Provide a mock function to simulate the result of a restore purchases operation during testing. Returns true to indicate success. ```swift Helium.testing.restoreHandler = { return true } ``` -------------------------------- ### Customize Paywall Presentation Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Configure specific paywall presentation behavior, such as setting a custom loading budget for slow connections or skipping display if the user is already entitled. ```swift let slowConnectionConfig = PaywallPresentationConfig( loadingBudget: 15.0 // 15 seconds for slow connections ) Helium.shared.presentPaywall( trigger: "premium", config: slowConnectionConfig, onPaywallNotShown: { _ in } ) // Skip if user already entitled let skipIfEntitledConfig = PaywallPresentationConfig( dontShowIfAlreadyEntitled: true ) // Add custom traits let customTraitsConfig = PaywallPresentationConfig( customPaywallTraits: HeliumUserTraits([ "source": "feature_request", "timestamp": Date() ]) ) ``` -------------------------------- ### getDownloadStatus() Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Retrieves the current download status of the paywall configuration. Possible statuses include not downloaded yet, in progress, download success, or download failure. ```APIDOC ## getDownloadStatus() ### Description Returns the current download status of paywall configuration. ### Method Signature `public func getDownloadStatus() -> HeliumFetchedConfigStatus` ### Returns One of `.notDownloadedYet`, `.inProgress`, `.downloadSuccess`, `.downloadFailure`. ### Example ```swift switch Helium.shared.getDownloadStatus() { case .downloadSuccess: print("Paywalls loaded") case .inProgress: print("Downloading...") case .downloadFailure: print("Download failed") default: break } ``` ``` -------------------------------- ### Accessing Experiment Info from Paywall Open Event Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Shows how to retrieve experiment and variant information from a `PaywallOpenEvent` using the `getEventExperimentInfo()` method. This is useful for understanding user allocation in A/B tests. ```swift PaywallEventHandlers() .onOpen { // Get experiment allocation for this trigger if let experimentInfo = event.getEventExperimentInfo() { print("Experiment: \(experimentInfo.experimentName ?? "unknown")") print("Variant: \(experimentInfo.chosenVariantDetails?.allocationName ?? "control")") } } ``` -------------------------------- ### Enable Paywall Previews in Development Builds Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumConfig.md Controls the triple-tap gesture for paywall previews in DEBUG and TestFlight builds. Enabled by default. ```swift public var paywallPreviewsAutoEnabledInDevBuilds: Bool = true ``` -------------------------------- ### Switch User Account Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Implement account switching by resetting Helium and then identifying the new user. This process involves clearing existing user data and re-initializing the SDK with the new user's ID. Ensure `autoInitialize` is set to `true` if you want the SDK to re-initialize automatically after resetting. ```swift func switchUser(newUserId: String) { Helium.resetHelium( clearUserId: true, clearUserTraits: true, autoInitialize: true ) { Helium.identify.userId = newUserId } } ``` -------------------------------- ### WebCheckoutProcessors OptionSet Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/types.md Defines external web checkout payment processors like Paddle and Stripe. Use this to enable specific processors. ```swift public struct WebCheckoutProcessors: OptionSet, Sendable, CustomStringConvertible { public let rawValue: Int public static let paddle = WebCheckoutProcessors(rawValue: 1 << 0) public static let stripe = WebCheckoutProcessors(rawValue: 1 << 1) public static let all: WebCheckoutProcessors = [.paddle, .stripe] } ``` -------------------------------- ### paywallsLoaded() Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Checks if the paywall configuration has been successfully downloaded. Returns a boolean value indicating the download status. ```APIDOC ## paywallsLoaded() ### Description Returns `true` if paywall configuration has been successfully downloaded. ### Method Signature `public func paywallsLoaded() -> Bool` ### Example ```swift if Helium.shared.paywallsLoaded() { print("Paywalls ready") } ``` ``` -------------------------------- ### Present Full-Screen Paywall Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/README.md Present a paywall as a full-screen modal. Customize behavior with event handlers and specify actions for when the paywall is not shown. ```swift Helium.shared.presentPaywall( trigger: "premium_upgrade", eventHandlers: PaywallEventHandlers() .onPurchaseSucceeded { unlockFeature() }, onPaywallNotShown: { reason in print("Paywall not shown: \(reason)") } ) ``` -------------------------------- ### createStripePortalSession(returnUrl:) Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Generates a Stripe Customer Portal session for managing subscriptions. It requires a return URL for redirection after the user completes their actions in the portal and throws an error if session creation fails. ```APIDOC ## createStripePortalSession(returnUrl:) ### Description Creates a Stripe Customer Portal session for subscription management. ### Method Signature `public func createStripePortalSession(returnUrl: String) async throws -> URL` ### Parameters #### Path Parameters - **returnUrl** (String) - Required - URL to redirect to after user finishes in portal ### Returns Portal session URL. ### Throws Error if session creation fails. ### Example ```swift do { let portalURL = try await Helium.shared.createStripePortalSession(returnUrl: "myapp://settings") await UIApplication.shared.open(portalURL) } catch { print("Failed: \(error)") } ``` ``` -------------------------------- ### Create Stripe Customer Portal Session Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/Helium.md Creates a Stripe Customer Portal session for subscription management. Redirects the user to the provided return URL after they finish in the portal. Throws an error if session creation fails. ```swift public func createStripePortalSession(returnUrl: String) async throws -> URL ``` ```swift do { let portalURL = try await Helium.shared.createStripePortalSession(returnUrl: "myapp://settings") await UIApplication.shared.open(portalURL) } catch { print("Failed: \(error)") } ``` -------------------------------- ### Enable External Web Checkout Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/configuration.md Configure the SDK to use external web-based checkout flows for payment processors like Stripe or Paddle. Specify success and cancel URLs. ```swift // Enable Stripe/Paddle web checkout Helium.config.enableExternalWebCheckout( successURL: "myapp://checkout/success", cancelURL: "myapp://checkout/cancel", paymentProcessors: .all // .paddle, .stripe, or .all ) ``` -------------------------------- ### Use in Event Handler Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md Demonstrates how to integrate experiment information into event handlers, specifically for paywall events. It allows accessing experiment details when a paywall is opened. ```APIDOC ## Use in Event Handler ### Description Demonstrates how to integrate experiment information into event handlers, specifically for paywall events. It allows accessing experiment details when a paywall is opened. ### Method ```swift Helium.shared.presentPaywall(...) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let handlers = PaywallEventHandlers() .onOpen { event in if let expInfo = event.getEventExperimentInfo() { print("Paywall in experiment: \(expInfo.experimentName ?? "unnamed")") print("Variant index: \(expInfo.chosenVariantDetails?.allocationIndex ?? 0)") } } Helium.shared.presentPaywall( trigger: "premium_upgrade", eventHandlers: handlers, onPaywallNotShown: { _ in } ) ``` ### Response #### Success Response - `event.getEventExperimentInfo()` (EventExperimentInfo?): Information about the experiment associated with the event. - `expInfo.experimentName` (String?): The name of the experiment. - `expInfo.chosenVariantDetails.allocationIndex` (Int?): The index of the chosen variant. #### Response Example ``` Paywall in experiment: premium_upgrade_variant_b Variant index: 1 ``` ``` -------------------------------- ### Paywall Integration with SwiftUI View Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Demonstrates how to present a paywall within a SwiftUI view using the `.heliumPaywall` modifier. It shows how to bind the paywall's presentation to a state variable and handle purchase success to dismiss the paywall. ```swift @State var isPaywallShown = false var body: some View { VStack { Button("Show Paywall") { isPaywallShown = true } } .heliumPaywall( isPresented: $isPaywallShown, trigger: "premium_upgrade", eventHandlers: PaywallEventHandlers() .onPurchaseSucceeded { unlockPremium() isPaywallShown = false }, fallbackView: { Text("Paywall unavailable") } ) } ``` -------------------------------- ### Builder Method for PaywallEventHandlers onOpen Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Builder method to set the open handler for PaywallEventHandlers. Returns self for chaining. ```swift public func onOpen(_ handler: @escaping (PaywallOpenEvent) -> Void) -> PaywallEventHandlers ``` ```swift PaywallEventHandlers() .onOpen { print("Opened") } .onClose { print("Closed") } ``` -------------------------------- ### Restore Purchase Configuration Class Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/types.md Configuration class for managing the 'restore failed' dialog. Allows disabling the dialog, customizing its text, or resetting to default settings. ```swift public class RestorePurchaseConfig { public func disableRestoreFailedDialog() public func setCustomRestoreFailedStrings( customTitle: String?, customMessage: String?, customCloseButtonText: String? ) public func reset() var showHeliumDialog: Bool { get } var restoreFailedTitle: String { get set } var restoreFailedMessage: String { get set } var restoreFailedCloseButtonText: String { get set } } ``` -------------------------------- ### Analytics Tracking with onAnyEvent Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/PaywallEventHandlers.md Illustrates setting up a catch-all event handler using `onAnyEvent` to log all paywall events for analytics purposes. This requires defining a custom delegate that conforms to HeliumPaywallDelegate. ```swift class AnalyticsDelegate: HeliumPaywallDelegate { var delegateType: String { "analytics" } func makePurchase(productId: String) async -> HeliumPaywallTransactionStatus { // Delegate to real purchase handler return .purchased } func restorePurchases() async -> Bool { return true } func onPaywallEvent(_ event: HeliumEvent) { // Log all events track(eventName: event.eventName, properties: event.toDictionary()) } } // Setup let handlers = PaywallEventHandlers() .onAnyEvent { print("Event: \(event.eventName)") } ``` -------------------------------- ### Log Experiment and Variant Metadata Source: https://github.com/cloudcaptainai/helium-swift/blob/main/_autodocs/api-reference/HeliumExperiments.md This snippet demonstrates how to access and print metadata associated with an experiment and its chosen variant. It's useful for debugging or understanding experiment configurations. ```swift if let experiment = Helium.experiments.infoForTrigger("onboarding") { if let metadata = experiment.experimentMetadataDictionary { print("Experiment metadata: \(metadata)") } if let variant = experiment.chosenVariantDetails { print("Variant metadata: \(variant.allocationMetadataDictionary ?? [:])") } } ```