Skip to content
NuxieNuxie
Esc
↑↓navigate↵open⌘Jpreview
Open Nuxie
On this page

Feature Gating

Check premium access, show an upgrade Experience, and consume metered usage.

Use a Feature to offer paid access without checking subscription products throughout your app. This guide connects premium-export to a Product, checks access before exporting, and shows an upgrade Experience when the customer needs it.

Step 1: Define a feature

In Features, choose Create Feature, enter a name such as Premium export, and set the Feature key to premium-export. Select Access (on or off). The key is what your app passes to the SDK.

Step 2: Add an entitlement to a product

Open the Product’s Entitlements tab, choose Grant Feature, and select premium-export. Confirm with Grant Feature. Customers with an active grant from this Product can use premium export.

See Features and entitlements for grant configuration.

Step 3: Check the feature in your app

// 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()
    }
}

hasFeature() uses fresh cached access and queries the server when needed. A failed request throws; handle that separately from a result with allowed: false.

Step 4: Show an upgrade paywall when not entitled

Trigger the upgrade Experience

Publish an Experience with the feature_locked event trigger:

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

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

Choose Every time if the customer should be able to request the upgrade repeatedly. Audience and other delivery rules still apply.

Dismissing a presented Experience

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

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

Dismissal waits for an in-progress purchase or restore. It does nothing when no Experience is visible.

Step 5: Handle the purchase and verify access

A completed checkout can update access asynchronously. Re-check access before performing the export, or observe feature changes so the UI updates when access becomes available:

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

For SwiftUI, observe feature changes directly:

// 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()
            }
        }
        .disabled(features.state == .unknown)
    }
}

Keep the button disabled while access is .unknown. Boolean access can update from a verified purchase; fixed balances require server confirmation. Purchases explains native and provider checkout.

Metered features: track and limit usage

Use a metered feature for a fixed allowance, such as API calls. For shared credits, query and consume the credit feature itself with the action’s cost.

Create a metered feature

Create a Feature with Metered usage selected and the Feature key api-calls. Your app records one unit for each accepted API call.

Add a metered entitlement

Open the Product’s Entitlements tab and choose Grant Feature. Select api-calls, choose Fixed units, and enter 1000 in Units. The Product now grants an allowance of 1,000 calls; your app consumes that allowance as customers use it.

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()
}

Consume usage before the action

Wait for accepted usage before making the API call:

// 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 {
    // Offer a retry for unavailable service; do not perform the API call.
}

The cached check controls the button; the usage result determines whether to run the API call. An accepted last use can leave a zero balance and still allow this call. For retries that must reuse the same operation ID, use consumeFeature().

After a native purchase, Nuxie can verify the purchase, grant its allowance, and deduct the first use together. The result’s authoritativeAccess contains updated access when available.

See Features and entitlements for query options and change notifications.

Last updated on

Was this page helpful?