Event model
How events are tracked, queued, batched and shipped — and how the typed e-commerce events relate to plain custom events.
The SDK's event model is offline-first and append-only. Every call to
track, customEvent or a typed e-commerce helper writes to a local SQLite
queue first, then flushes to the Swan backend on a background scheduler. If
the network is down the queue grows; when connectivity returns it drains with
exponential-backoff retry.
Event families
| Family | Examples | When to use |
|---|---|---|
| Lifecycle (auto) | sessionStarted, sessionEnded, appOpened, appBackgrounded | Emitted automatically by the SDK; you don't call these |
| Screen tracking | SwanEvents.screen("ProductDetail", attrs) | One call per screen view |
| E-commerce (typed) | productViewed, productAddedToCart, checkoutCompleted, orderCompleted, search, categoryViewedPage | Use these when applicable — they emit a canonical schema the campaigns engine knows |
| Custom | Swan.customEvent("clickedHero", { variant: "A" }) | Anything domain-specific |
The typed e-commerce helpers exist because the Swan backend's campaign engine
recognises those event names + payload shapes and can target / segment on them.
A free-form customEvent("productViewed", ...) will land but won't be picked
up as e-commerce data — use the typed helper.
Super-properties
Some attributes apply to every subsequent event — country, currency, business unit, current screen. Set these once and they ride along automatically:
Swan.setCountry("AE")
Swan.setCurrency("AED")
Swan.setBusinessUnit("loyalty-app")
Swan.setCurrentScreenName("ProductDetail")Every event tracked after these calls carries those values without you passing them per-event.
Batching and flush
| Trigger | When |
|---|---|
| Time-based | Every 30s while events are in queue |
| Size-based | When the pending count reaches the batch size (default 10) |
| Lifecycle | App foreground / background transitions |
| Manual | Swan.flush() for tests / forced uploads |
A failed flush re-enqueues with exponential backoff (max 60s) and resumes on next network change.
Sessions
A session is the time between an app foreground and the next 20-minute
inactivity gap. The SDK manages this transparently via the platform's
lifecycle observer (Android ProcessLifecycleOwner, iOS scene lifecycle,
RN AppState).
Anything you track inside a session inherits the sessionId, so you can
reconstruct a user journey downstream without doing client-side session math.