Skip to content
Nuxie
Esc
navigateopen⌘Jpreview
On this page

Feature Gating

Gate premium features behind product purchases

Use features and entitlements to control access to premium capabilities. Check entitlements from the SDK, show an upgrade paywall when users lack access, and handle metered usage for consumption-based features.

Prerequisites:

  • A Nuxie account with an app and at least one product configured
  • The iOS SDK installed and configured (see Quickstart)
  • Native StoreKit, or an optional provider/custom delegate (see Purchases)

Step 1: Define a feature

Navigate to Features in your app’s dashboard. Click Create Feature and configure:

  • Name – “Premium Export”
  • External IDpremium_export
  • Type – Boolean

Boolean features are simple on/off access checks. The user either has the feature or does not. No additional configuration is needed.

Step 2: Add an entitlement to a product

Open your product (e.g., “Pro Monthly”) and go to the Entitlements tab. Click Add Entitlement and select the premium_export feature.

For boolean features, the entitlement is straightforward: owning the product grants access. The interval is automatically set to lifetime.

Now any user who purchases the Pro Monthly product receives the premium_export entitlement.

Step 3: Check the feature in your app

Use hasFeature() to check access at runtime:

// nuxie-doc-fragment: gate-feature-in-task harness=sync-body
Task {
    let access = try await NuxieSDK.shared.hasFeature("premium_export")
    if access.allowed {
        performExport()
    } else {
        showUpgradePrompt()
    }
}

The default cache-first policy serves fresh authenticated profile state and asks the server when the cache is absent or stale.

Step 4: Show an upgrade paywall when not entitled

When the feature check returns allowed: false, trigger a paywall. There are two approaches:

Approach A: Trigger an experience

Fire a named event that your experience is configured to respond to:

// nuxie-doc-snippet: trigger-upgrade-prompt
import Nuxie

func showUpgradePrompt() {
    NuxieSDK.shared.trigger("feature_locked")
}

In the dashboard, create an experience with an event trigger for feature_locked and a re-entry policy of Every time. This way, tapping the locked feature always presents the paywall.

Dismissing a presented Experience

The engine owns presentation: an Experience appears because a trigger matched a campaign, and the journey decides when it ends. When the app itself needs to end a presentation (a deep link arriving, a sign-out), call dismiss():

// nuxie-doc-snippet: dismiss-upgrade-prompt
import Nuxie

@MainActor
func closeAnyPresentedExperience() {
    Task {
        await NuxieSDK.shared.dismiss()
    }
}

dismiss() is a no-op when nothing is presented. It waits for an in-flight purchase or restore rather than interrupting StoreKit, then exits the journey as dismissed.

Step 5: Handle the purchase and verify access

After the user purchases from the paywall, the SDK syncs the transaction with the server. The entitlement updates immediately, and the feature check returns allowed: true:

// nuxie-doc-fragment: recheck-access-after-purchase harness=async-body
// After purchase completes, re-check
let access = try await NuxieSDK.shared.hasFeature("premium_export")
// access.allowed is now true

For SwiftUI apps, observe the reactive feature map to update your UI automatically:

// nuxie-doc-snippet: reactive-export-button
import Nuxie
import SwiftUI

struct ExportButton: View {
    @ObservedObject var features = NuxieSDK.shared.features

    var body: some View {
        Button("Export") {
            if features.isAllowed("premium_export") {
                performExport()
            } else {
                showUpgradePrompt()
            }
        }
    }
}

FeatureInfo is an ObservableObject that updates whenever feature access changes – after purchases, profile refreshes, or real-time entitlement checks.

Metered features: track and limit usage

For consumption-based features like API calls or credits, use metered features instead of boolean features.

Create a metered feature

In the dashboard, click Create Feature with:

  • Name – “API Calls”
  • External IDapi_calls
  • Type – Metered (single use)
  • Event name (optional) – the event that triggers automatic usage tracking

Add a metered entitlement

On your product’s Entitlements tab, add the api_calls feature with:

  • Allowance type – Fixed
  • Allowance – 1000
  • Reset interval – Month
  • Carry from previous – No

This grants 1,000 API calls per month. The balance resets at the start of each billing period.

Check balance for presentation

// nuxie-doc-fragment: metered-api-call-access harness=async-body
let access = try await NuxieSDK.shared.hasFeature(
    "api_calls",
    requiredBalance: 1
)
if access.allowed {
    // Show the enabled state. Authoritative consumption still happens below.
    showEnabledApiCallButton()
} else {
    // Balance exhausted -- show upgrade prompt
    showUpgradePrompt()
}

Reserve usage before the side effect

For a fixed allowance or credit-backed operation, wait for the server to accept the deduction before performing the protected side effect:

// nuxie-doc-fragment: consume-metered-api-call harness=async-body
do {
    let result = try await NuxieSDK.shared.useFeatureAndWait("api_calls", amount: 1)
    guard result.success else {
        showUpgradePrompt()
        return
    }
    performApiCall()
} catch {
    // Includes an exhausted balance or unavailable authoritative service.
    showUpgradePrompt()
}

The cached check keeps the interface responsive, but it is not authority to spend a newly purchased or otherwise unconfirmed fixed balance. Immediately after a native App Store purchase, useFeatureAndWait() automatically attaches the matching protected transaction evidence. Nuxie verifies the purchase, grants the allowance, and consumes this use as one idempotent server operation. The result’s authoritativeAccess contains the resulting access and balance.

useFeature() remains useful for telemetry or optimistic counters whose side effect does not depend on that balance; do not use it to authorize quota- or credit-backed work.

Next steps

Last updated on August 24, 2026

Was this page helpful?