---
title: "Presenting Experiences"
description: "Trigger an Experience, receive App Actions, and dismiss the presentation."
search:
  tags: ["sdk", "reference", "ios"]
  keywords: ["Swift", "StoreKit", "Xcode"]
---

Display an onboarding flow, paywall, or survey at an app event by calling `trigger()`. The SDK checks the Experience's published delivery rules and presents it in a native window above your app; you can change its content and audience in Nuxie without changing the call.

<span id="before-you-begin" />

[Configure the SDK](/docs/ios-sdk/configuration) and [publish an Experience](/docs/guides/publishing) before sending its trigger.

## Send the published trigger

```swift
// nuxie-doc-fragment: trigger-experience-event harness=sync-body
NuxieSDK.shared.trigger("export_limit_reached")
```

Use the exact event name from **Connect your app**. Send it from the relevant app action, such as tapping an upgrade button or reaching an export limit.

`trigger()` returns immediately. Presentation depends on the published audience, re-entry rules, and current Journey state. You do not present a view controller yourself.

## Verify presentation

Run the app and perform the action that sends the event. The screen appears on the device, and **Connect your app** shows **Shown**.

<span id="authored-actions" />

## Actions

Experiences can navigate between screens, purchase or restore products, collect responses, request permissions, open links, and send events. Use an App Action to connect those screens to your app, such as opening a library after onboarding or continuing an export after an upgrade.

### Run App Actions

Implement `NuxieDelegate` and assign it to `NuxieSDK.shared.delegate`:

```swift
// nuxie-doc-snippet: receive-app-action
import Nuxie

@MainActor
final class ExperienceActions: NuxieDelegate {
    func nuxie(_ sdk: NuxieSDK, didRequestAppAction action: AppAction) {
        guard action.name == "export_finished" else { return }
        // Validate action.payload before performing sensitive work.
    }
}
```

`action.name` identifies the action. `action.payload` contains its resolved data, and `action.experience` identifies the Experience version and Journey. Validate the payload before using it for sensitive operations.

Store an `ExperienceActions` instance in an app-owned property, then assign that instance to `NuxieSDK.shared.delegate`. The SDK holds the delegate weakly, so a temporary instance stops receiving callbacks when it is released. Callbacks run on the main actor; implement only the methods you need.

### Observe activity

Implement `nuxieDidEmit(_ info: NuxieActivityInfo)` to forward Experience activity to analytics or update app UI. Attach the delegate before the activity you want to observe; the callback does not replay historical events.

| Field | Description |
| --- | --- |
| `id` | Stable event ID, suitable for deduplication when forwarding. |
| `customerId` | Customer associated with the activity. |
| `timestamp`, `receivedAt` | When the activity happened and when the device received it. |
| `activity` | Typed `NuxieActivity` value. |
| `name`, `properties` | Analytics-ready name and scalar property map. |
| `isCurrentIdentity` | Whether the original customer session is still active. |

`NuxieActivityInfo.schemaVersion` identifies the activity format. Property values are `.string`, `.int`, `.double`, or `.bool`. Check `isCurrentIdentity` before changing customer-specific UI; forwarded analytics can retain the original `customerId`.

Activities include Experience and screen presentation, Journey start and completion, purchase and restore outcomes, purchase synchronization, accepted feature usage, experiment exposure, permissions, and app lifecycle events. They report what happened independently of the `trigger()` call.

## Dismissing a presentation

```swift
// nuxie-doc-fragment: dismiss-presented-experience harness=async-body
await NuxieSDK.shared.dismiss()
```

Call `dismiss()` when the app needs to close the Experience, such as on sign-out. It does nothing when no Experience is visible. An in-progress purchase or restore finishes before dismissal.

## If the Experience does not appear

| Check | What to look for |
| --- | --- |
| Connection | Setup succeeded and **Connect your app** shows **Connected**. |
| Event | The exact published trigger is sent after setup. |
| Publishing | The Experience is live for the same app and environment. |
| Targeting | The customer matches the audience and can re-enter. |
| Presentation | Another Experience is not already visible. |
| Logs | Look for loading or version-compatibility errors. |

See [Delivery](/docs/guides/delivery) for targeting rules and [Privacy and logging](/docs/ios-sdk/privacy-and-logging) for diagnostics.

## Presentation shell

The SDK handles loading, errors, safe areas, color scheme, and closing. One Experience is visible at a time. A Journey can continue after its visible screen closes.

## How releases reach the device

Publishing creates an immutable Experience version. The SDK fetches and verifies the published version before displaying it. In-progress Journeys keep their existing version.

## Release preparation and caching

The SDK downloads eligible content after profile synchronization and caches it for reuse. Missing assets can be downloaded when presentation is requested. Downloads may pause when the app backgrounds or memory is constrained.

<span id="next-steps" />

See [Tracking events](/docs/ios-sdk/tracking-events) for event properties and [Purchases](/docs/ios-sdk/purchases) for checkout actions.
