Tracking Events
Send events from your app to power segments, experiences, and analytics
Events are the foundation of Nuxie’s targeting and analytics. Track user actions to trigger experiences, build segments, and measure performance.
The trigger method
Use trigger() to send an event. It works as a fire-and-forget call, but also returns a TriggerHandle you can observe for experience decisions and entitlement updates.
// Fire-and-forget
NuxieSDK.shared.trigger("item_added_to_cart", properties: [
"item_id": "sku_999",
"price": 29.99
])
Method signature
@discardableResult
public func trigger(
_ event: String,
properties: [String: Any]? = nil,
userProperties: [String: Any]? = nil,
userPropertiesSetOnce: [String: Any]? = nil,
handler: ((TriggerUpdate) -> Void)? = nil
) -> TriggerHandle
| Parameter | Description |
|---|---|
event |
The event name. Use a descriptive string like "checkout_started". System events use a $ prefix. |
properties |
Key-value pairs attached to this specific event. |
userProperties |
Properties to set on the user profile (mapped to $set). |
userPropertiesSetOnce |
Properties to set only if not already present (mapped to $set_once). |
handler |
An optional callback that receives progressive TriggerUpdate values as the event is processed. |
Observing trigger outcomes
The returned TriggerHandle conforms to AsyncSequence and delivers TriggerUpdate values:
let handle = NuxieSDK.shared.trigger("paywall_trigger")
for await update in handle {
switch update {
case .decision(let decision):
print("Decision: \(decision)")
case .entitlement(let entitlement):
print("Entitlement: \(entitlement)")
case .journey(let journey):
print("Journey: \(journey)")
case .error(let error):
print("Error: \(error)")
}
}
You can also use the callback parameter for the same updates:
NuxieSDK.shared.trigger("paywall_trigger") { update in
// Called on the main thread
switch update {
case .decision(.flowShown):
print("Flow is now visible")
default:
break
}
}
Event properties
Attach structured data to any event:
NuxieSDK.shared.trigger("purchase_started", properties: [
"product_id": "com.app.premium",
"price": 9.99,
"currency": "USD",
"source": "settings_screen"
])
Properties are stored locally and delivered to the server in batches. They are available in segments, experience conditions, and analytics.
System events
The SDK automatically tracks system events prefixed with $. These events are used internally for experience triggers, segment evaluation, and analytics.
| Event | When tracked | Description |
|---|---|---|
$app_installed |
First launch | The app launched for the first time on this device. |
$app_updated |
Launch after version change | The app launched with a different version than the previous session. |
$app_opened |
Every launch | The app opened, including first launch, updates, and foreground returns. |
$app_backgrounded |
App enters background | The app moved to the background. |
$identify |
identify() called |
A user identity was linked. Includes distinct_id and $anon_distinct_id. |
$journey_enrolled |
Experience triggers | An experience run was enrolled with its version and settings frozen. |
$journey_transition |
Journey advances | The run advanced to another node at the next transition epoch. |
$journey_milestone |
Milestone action runs | The run recorded a named milestone. |
$journey_converted |
Goal converts | The device reported or server confirmed conversion. |
$journey_exited |
Journey finishes | The run exited with a terminal reason. |
$experience_shown |
Experience presented | An experience was displayed to the user. |
$experience_dismissed |
Experience dismissed | The user dismissed an experience. |
$experience_purchased |
Purchase from experience | A purchase completed from an experience. |
$experience_timed_out |
Experience timed out | Presentation exceeded its time limit. |
$experience_errored |
Experience failed | Presentation failed. |
$experience_artifact_load_succeeded |
Artifact loaded | The experience version artifact loaded. |
$experience_artifact_load_failed |
Artifact load failed | The experience version artifact failed to load. |
$purchase_completed |
Purchase succeeds | A StoreKit purchase completed. |
$purchase_synced |
Transaction synced | A transaction was verified and synced to the server. |
$restore_completed |
Restore succeeds | A purchase restore completed. |
$feature_used |
useFeature() called |
Feature usage was reported. |
Tip: Name your custom events without the
$prefix. The$prefix is reserved for SDK system events.
How events are processed
When you call trigger(), the event flows through these stages:
- Snapshot – the current distinct ID and session ID are captured at call time.
- Enrich – device context (OS version, app version, device model) is attached.
- Sanitize – data types are normalized and any configured sanitizer is applied.
- Store – the event is persisted to a local database for segment evaluation and history.
- Route – the event is forwarded to the experience engine for trigger matching.
- Deliver – the event is added to the network queue for batch delivery to the server.
If a beforeSend hook is configured, it runs between step 3 and step 4. Returning nil from beforeSend drops the event entirely.
Batching and delivery
Events are delivered to the server in batches for efficiency:
- The queue flushes automatically when it reaches the
flushAtthreshold (default: 20 events). - A periodic timer flushes remaining events every
flushIntervalseconds (default: 30). - When the app enters the foreground, the queue flushes immediately.
- When the app enters the background, automatic flushing pauses.
To flush manually:
await NuxieSDK.shared.flushEvents()
Storage limits
Events are stored locally in a database for segment evaluation and experience matching:
- Maximum stored events: 10,000
- Retention period: 30 days
Events beyond these limits are automatically cleaned up. Network delivery is handled separately through the in-memory batch queue.
Next steps
- Presenting Flows – learn how events trigger experiences
- Segments – see how event history feeds segment evaluation
- Privacy & Logging – configure sanitizers and the
beforeSendhook