Event Tracking
Custom Events
// Simple event
AttributeHQ.shared.track(eventName: "signup_completed")
// Event with properties
AttributeHQ.shared.track(eventName: "product_viewed", properties: [
"product_id": "sku_123",
"category": "electronics",
"price": 15000
])Revenue Events
// Basic revenue (defaults to NGN)
AttributeHQ.shared.trackRevenue(amount: 5000)
// With currency
AttributeHQ.shared.trackRevenue(amount: 25.99, currency: "USD")
// With properties
AttributeHQ.shared.trackRevenue(amount: 5000, currency: "NGN", properties: [
"product": "premium_plan",
"payment_method": "card"
])Report actual earned revenue, not deposits or transaction volume. Do not also track a transaction collected through RevenueCat; that would risk double counting. Client-reported revenue is not a trusted backend purchase confirmation.
User Identification
AttributeHQ.shared.identify(userId: "user_12345", properties: [
"plan": "premium"
])Get Attribution
if let attribution = AttributeHQ.shared.getAttribution() {
print("Match type: \(attribution.matchType)")
print("Confidence: \(attribution.confidence)%")
print("Source: \(attribution.mediaSource ?? "organic")")
print("Campaign: \(attribution.campaignId ?? "none")")
print("Organic: \(attribution.isOrganic)")
}Returns nil if install tracking has not completed. The current iOS organic fallback is not proof of unpaid acquisition; paid attribution remains unvalidated.
Flush Events
Events are automatically flushed based on batchSize and flushInterval. To force a flush:
AttributeHQ.shared.flush()Background Behavior
When the app enters background (UIApplication.didEnterBackgroundNotification):
- The SDK starts a
beginBackgroundTask - All queued events are flushed
- Background task ends when flush completes or times out
Background execution is limited by iOS; delivery is best effort and may resume on a later launch.
Offline Queue
Events are persisted to disk. If a flush fails (no network), events stay in the queue and are retried on the next flush cycle. The NWPathMonitor detects connectivity changes to optimize flush timing.
If the queue exceeds maxQueueSize (default: 100), the oldest events are dropped.