iOS SDK - Tracking In-app Events

Tracking In-App Events

Track in-app events to analyze campaign performance and measure key performance indicators (KPIs) such as user logins, registrations, tutorial completions, or progression milestones.

Standard Events and Attributes

Using Standard Events

Singular supports standard events that are recognized by ad networks for reporting and optimization. Use standard event names whenever possible for automatic recognition and simplified setup.

Your UA, marketing, or business team should compile the list of events based on your organization's marketing KPIs. Reference the guide How to Track In-App Events: Guide For Singular Attribution Customers for planning.

Each event supports various attributes. See the recommended standard attributes per event for implementation details.


Sending Events

Event Implementation Guidelines

Send events to Singular using the event or eventWithArgs methods for tracking user actions and behaviors.

  • Standard Events: Use the event's iOS name from the standard events list, e.g., EVENT_SNG_LOGIN
  • Custom Events: For events unique to your app that don't match standard events, use any descriptive string that complies with the character limitations

Custom Event Limitations:

  • Language: Pass event names and attributes in English to ensure compatibility with third-party partners and analytics solutions
  • Event Names: Limited to 32 ASCII characters. Non-ASCII strings must be under 32 bytes when converted to UTF-8
  • Attributes and Values: Limited to 500 ASCII characters

event Method

Report user events without additional information for simple tracking scenarios.

Method Signature:

+ (void)event:(NSString *)name;

Usage Examples

SwiftObjective-C
// Example 1: Standard event
Singular.event(EVENT_SNG_LOGIN)

// Example 2: Custom event
Singular.event("signup")

eventWithArgs Method

Report user events with additional information using dictionary format for structured data.

Method Signature:

+ (void)event:(NSString *)name withArgs:(NSDictionary *)args;

Note: The args parameter is an NSDictionary containing one or more key-value pairs. Keys must be strings and values can be any type allowed in an NSDictionary.

Usage Examples

SwiftObjective-C
// Example 1: Standard event with recommended attributes
var dic: [AnyHashable: Any] = [:]
dic[ATTRIBUTE_SNG_ATTR_CONTENT_TYPE] = "video"
dic[ATTRIBUTE_SNG_ATTR_CONTENT_ID] = "32"
dic[ATTRIBUTE_SNG_ATTR_CONTENT] = "Telugu"
dic[ATTRIBUTE_SNG_ATTR_SUCCESS] = "yes"

Singular.event(EVENT_SNG_TUTORIAL_COMPLETE, withArgs: dic)

// Example 2: Custom event with custom attributes
var bonusData: [AnyHashable: Any] = [
    "level": 10,
    "points": 500
]
Singular.event("Bonus Points Earned", withArgs: bonusData)

Tracking In-App Revenue

Track revenue from in-app purchases (IAP), subscriptions, and custom revenue sources to measure campaign performance and return on ad spend (ROAS).

Revenue data flows through three channels:

  • Interactive Reports: View revenue metrics in the Singular dashboard
  • Export Logs: Access detailed ETL data for custom analysis
  • Real-Time Postbacks: Send revenue events to external platforms

Revenue Event Limitations:

  • Event Names: Custom revenue event names are limited to 32 ASCII characters (or 32 bytes for non-ASCII when converted to UTF-8)
  • Attributes: Event attribute names and values are limited to 500 ASCII characters
  • Currency Codes: Must be ALL CAPS and follow the three-letter ISO 4217 standard (e.g., USD, EUR, INR)

Best Practices

  • Standard Naming: Use Singular's standard event and attribute naming convention
  • Language: Send custom revenue event names in English for improved ad network postback compatibility
  • Non-Zero Amounts: Only send revenue events when the amount is greater than or less than 0

Non-Subscription In-App Purchase

SKPaymentTransaction Integration

Pass the SKPaymentTransaction object from StoreKit to the iapComplete method for enriched reporting and transaction validation.

Benefits:

  • Rich Data: Singular receives complete transaction details for comprehensive reports
  • Fraud Prevention: Transaction receipts enable validation to combat in-app fraud

Notes:

  • Required Object: The iapComplete method requires the SKPaymentTransaction object
  • Currency Conversion: Revenue in different currencies is automatically converted to your organization's preferred currency
  • Custom Event Names: Use the withName parameter to categorize revenue by event type in reports

iapComplete Method

Send a revenue event with the SKPaymentTransaction object for automatic validation and enriched data.

Method Signatures:

+ (void)iapComplete:(id)transaction;
+ (void)iapComplete:(id)transaction withName:(NSString *)name;

Usage Examples

SwiftObjective-C
// Get the SKPaymentTransaction object
let transaction: SKPaymentTransaction = ...

// Send transaction without custom event name
Singular.iapComplete(transaction)

// Send transaction with custom event name
Singular.iapComplete(transaction, withName: "MyCustomRevenue")

Subscription Revenue

Subscription Event Implementation

Track subscription purchases and renewals to gain insights into user behavior and recurring revenue generation.

Implementation Guide: Review the comprehensive Subscription Event Technical Implementation Guide for detailed instructions on tracking subscriptions with the Singular SDK.


Custom Revenue without Purchase Validation

Manual Revenue Tracking

Track revenue by passing currency, amount, and optional product details without the SKPaymentTransaction object. Note that this method does not provide transaction receipts for validation.

Important: When using these methods, Singular cannot validate transactions. We strongly recommend using the SKPaymentTransaction methods described above whenever possible.


revenue Method

Send revenue events with currency, amount, and optional product details.

Method Signatures:

+ (void)revenue:(NSString *)currency amount:(double)amount;

+ (void)revenue:(NSString *)currency 
         amount:(double)amount
     productSKU:(NSString *)productSKU 
    productName:(NSString *)productName 
productCategory:(NSString *)productCategory
productQuantity:(int)productQuantity 
   productPrice:(double)productPrice;

+ (void)revenue:(NSString *)currency 
         amount:(double)amount
 withAttributes:(NSDictionary *)attributes;

Usage Examples

SwiftObjective-C
// Without product details
Singular.revenue("USD", amount: 1.99)

// With product details
Singular.revenue("EUR", 
    amount: 5.00, 
    productSKU: "SKU1928375", 
    productName: "Reservation Fee",
    productCategory: "Fee", 
    productQuantity: 1, 
    productPrice: 5.00)

// With product details in a dictionary
var dic: [AnyHashable: Any] = [:]
dic[ATTRIBUTE_SNG_ATTR_ITEM_DESCRIPTION] = "100% Organic Cotton Mixed Plaid Flannel Shirt"
dic[ATTRIBUTE_SNG_ATTR_ITEM_PRICE] = "$69.95"
dic[ATTRIBUTE_SNG_ATTR_RATING] = "5 Star"
dic[ATTRIBUTE_SNG_ATTR_SEARCH_STRING] = "Flannel Shirt"

Singular.revenue("USD", amount: 19.95, withAttributes: dic)

customRevenue Method

Send custom revenue events with a specified event name, currency, amount, and optional transaction attributes.

Method Signatures:

+ (void)customRevenue:(NSString *)eventName 
             currency:(NSString *)currency 
               amount:(double)amount;

+ (void)customRevenue:(NSString *)eventName 
             currency:(NSString *)currency 
               amount:(double)amount 
           productSKU:(NSString *)productSKU 
          productName:(NSString *)productName
      productCategory:(NSString *)productCategory 
      productQuantity:(int)productQuantity
         productPrice:(double)productPrice;

+ (void)customRevenue:(NSString *)eventName 
             currency:(NSString *)currency 
               amount:(double)amount 
       withAttributes:(NSDictionary *)attributes;

Usage Examples

SwiftObjective-C
// Without product details
Singular.customRevenue("MyCustomRevenue", currency: "USD", amount: 1.99)

// With product details
Singular.customRevenue("MyCustomRevenue", 
    currency: "EUR", 
    amount: 5.00, 
    productSKU: "SKU1928375", 
    productName: "Reservation Fee", 
    productCategory: "Fee", 
    productQuantity: 1, 
    productPrice: 5.00)

// With product details in a dictionary
var dic: [AnyHashable: Any] = [:]
dic[ATTRIBUTE_SNG_ATTR_ITEM_DESCRIPTION] = "100% Organic Cotton Mixed Plaid Flannel Shirt"
dic[ATTRIBUTE_SNG_ATTR_ITEM_PRICE] = "$69.95"
dic[ATTRIBUTE_SNG_ATTR_RATING] = "5 Star"
dic[ATTRIBUTE_SNG_ATTR_SEARCH_STRING] = "Flannel Shirt"

Singular.customRevenue("CustomRevenueWithArgsDic", 
    currency: "USD", 
    amount: 44.99, 
    withAttributes: dic)

StoreKit2 Support

StoreKit2 Revenue Tracking

For apps using the StoreKit2 framework, use the customRevenue method with transaction and product JSON representations.

Important: Purchase validation is not supported for StoreKit2. The methods require jsonRepresentation format for transaction and product objects.

Method Signatures:

+ (void)customRevenue:(NSData *)transactionJsonRepresentation 
productJsonRepresentation:(NSData *)productJsonRepresentation;

+ (void)customRevenue:(NSString *)eventName 
transactionJsonRepresentation:(NSData *)transactionJsonRepresentation 
productJsonRepresentation:(NSData *)productJsonRepresentation;

Usage Examples

SwiftObjective-C
// Fetch transaction and product from StoreKit2
let transaction = ... // Valid StoreKit2 transaction
let product = ... // Valid StoreKit2 product

// Custom Revenue with default __iap__ event name
Singular.customRevenue(
    transactionJsonRepresentation: transaction.jsonRepresentation, 
    productJsonRepresentation: product.jsonRepresentation)

// Custom Revenue with custom event name
Singular.customRevenue(
    "PaymentSuccess", 
    transactionJsonRepresentation: transaction.jsonRepresentation, 
    productJsonRepresentation: product.jsonRepresentation)

Hybrid Event Tracking (Advanced)

Send all events and revenue through the Singular SDK integrated into your app for optimal attribution. However, Singular can collect events from other sources when necessary.

Events sent outside the Singular SDK must comply with Singular's Server-to-Server Event documentation and provide matching device identifiers for correct attribution.

Important:

Discrepancies occur when device identifiers in server-to-server requests don't match identifiers recorded by the Singular SDK:

  • Early Events: If an event arrives before the Singular SDK records the device identifier, the event becomes the "first session" for an unknown device, resulting in organic attribution
  • Mismatched Identifiers: If the Singular SDK recorded a different device identifier than the one in the server-to-server request, the event will be attributed incorrectly

Hybrid Event Tracking Guides

Sending Events from an Internal Server

Collect revenue data from your internal server to analyze campaign performance and ROI.

Requirements:

  • Capture Device Identifiers: During in-app registration or login events, capture and pass device identifiers, then store this data with the User ID on your server. Update identifiers when users generate new app sessions to ensure correct attribution
  • Platform-Specific Identifiers: Send server-side events with the device identifier matching the platform (e.g., IDFA or IDFV for iOS devices)
  • Real-Time Updates: Use the Singular Internal BI postback mechanism to push events in real-time to your endpoint. See the Internal BI Postback FAQ
  • Implementation Details: Review the "Tracking Revenue" section in the Server-to-Server Integration guide

Sending Events from a Revenue Provider

Integrate third-party revenue providers like RevenueCat or adapty to send purchase and subscription revenue to Singular.

Supported Providers:


Sending Events from Segment

Enable Segment to send events to Singular in parallel with the Singular SDK by adding a "Cloud-Mode" destination in Segment.

Follow the implementation guide Singular-Segment Integration for detailed setup instructions.