Swan SDK
Concepts

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

FamilyExamplesWhen to use
Lifecycle (auto)sessionStarted, sessionEnded, appOpened, appBackgroundedEmitted automatically by the SDK; you don't call these
Screen trackingSwanEvents.screen("ProductDetail", attrs)One call per screen view
E-commerce (typed)productViewed, productAddedToCart, checkoutCompleted, orderCompleted, search, categoryViewedPageUse these when applicable — they emit a canonical schema the campaigns engine knows
CustomSwan.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

TriggerWhen
Time-basedEvery 30s while events are in queue
Size-basedWhen the pending count reaches the batch size (default 10)
LifecycleApp foreground / background transitions
ManualSwan.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.

On this page