Tracking In-app Events
Note: For details on planning user events, see Will the App Track User Events? in the SDK Planning and Prerequisites guide.
Note: We recommend sending all in-app events to the Singular server using Singular SDK methods in your app. If you plan to send events to Singular from another provider or an internal server, see the Hybrid Event Tracking section below.
Tracking Events (Non Revenue)
Singular can collect data about in-app events to help analyze the performance of your campaigns and measure KPIs. For example, your organization may want to collect data about user logins, registrations, tutorial completions, or leveling up in a gaming app.
The list of events sent to Singular (with the accompanying attributes) should be compiled by the UA/marketing/business team based on your Marketing KPIs.
For more details on planning user events, see Will the App Track User Events? in the SDK Planning and Prerequisites guide.
In your code, send standard events to Singular using the event or eventWithArgs methods.
Note: For standard events, use the event's iOS name as it appears in the iOS SDK List of Standard Events and Attributes, e.g., EVENT_SNG_LOGIN.
For custom events, events that your organization wants to measure that do not match any of Singular's standard events, use any custom name (maximum of 32 characters). We recommend using names in English for compatibility with any ad network partners that may receive the event from Singular for optimization purposes.
event Method | |
---|---|
Description | Send a user event to Singular for tracking. |
Signature | (void)event:(NSString *)name |
Usage Example |
|
eventWithArgs Method | |
Description | Send a user event to Singular for tracking, with additional information. |
Signature | (void)eventWithArgs:(NSString *)name, ... |
Usage Example |
|
Tracking In-app Revenue
Singular captures revenue events from in-app purchases (IAP), subscriptions, and custom revenue to measure campaign performance and return on ad spend (ROAS). The revenue data becomes available through three key channels:
- Interactive reports in the Singular dashboard
- Detailed export logs and ETL data destinations for custom analysis
- Real-time postbacks to external platforms
This comprehensive revenue tracking enables data-driven decisions about marketing spend and campaign optimization while providing flexibility in how you consume and analyze the data.
Requirements
- If Custom Revenue Event Names are used the Custom Revenue Event Names are limited to 32 ASCII characters. For non-ASCII characters, the limit is 32 bytes once converted to UTF-8.
- Event attribute names and attribute values are limited to 500 ASCII characters.
-
Pass currency as a three-letter ISO 4217 currency code:
USD, EUR, INR
Best Practice
- Singular recommends passing events using Singular's standard event and attribute naming convention.
- If Custom Revenue Event Names are used they should be sent in English to improve compatibility with Ad Network postbacks.
- Revenue Events should only be sent to Singular when the Revenue Amount is greater than or less than 0.
Non-Subscription In-App Purchase
Important: This method does not support Subscription tracking! Use this method for Non-Subscription In-App purchase tracking.
If your app uses App Store IAP tracking, the recommendation is to use the iapComplete method.
This method sends an IAP (Apple's In-App Purchase) revenue event to Singular with:
- All the transaction details, which Singular will use to enrich reports.
- The transaction receipt, will be used to validate the transaction and analyze or prevent fraud attempts.
Notes:
- When using the iapComplete, you must include the SKPaymentTransaction object in the event.
- Any revenue reported in a different currency will be auto-converted to your organization's preferred currency, as set in your Singular account.
iapComplete Method
Send a revenue event to Singular with the transaction receipt.
Signatures
(void)iapComplete:(id)transaction
(void)iapComplete:(id)transaction withName:(NSString *)name;
Usage Examples
// *** Get the SKPaymentTransaction* transaction object ***
let transaction:SKPaymentTransaction = ...
// Send a transaction event to Singular without a custom event name
Singular.iapComplete(transaction)
// Send a transaction event to Singular with a custom event name
Singular.iapComplete(transaction, withName:"MyCustomRevenue")
// *** Get the SKPaymentTransaction* transaction object ***
SKPaymentTransaction* transaction = ...;
// Send a transaction event to Singular without a custom event name
[Singular iapComplete:transaction];
// Send a transaction event to Singular with a custom event name
[Singular iapComplete:transaction withName:@"MyCustomRevenue"];
Subscription Revenue
Tracking Subscriptions:
Singular enables you to track your subscriptions and renewals within your app, providing insights into user behavior and revenue generation. Review our comprehensive guide on how to implement subscription events using the Singular SDK. [Subscription Event Technical Implementation Guide]
Custom Revenue without Purchase Validation
If your app does not support App Store In-App Purchase tracking, the revenue or customRevenue methods are recommended. These methods do not perform purchase validation and should not include purchase object or receipt.
The revenue and customRevenue methods let you specify the transaction amount and currency manually, as well as optional additional details, such as the product serial number and quantity, etc. The customRevenue method also lets you pass a custom event name.
Note: if you use these methods, Singular does not validate the purchase transaction.
revenue Method
Send a revenue event to Singular with the revenue amount, currency, and optional details.
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
// Revenue with no product details
Singular.revenue("USD", amount:1.99)
// Revenue with product details
Singular.revenue("EUR", amount:5.00,
productSKU:"SKU1928375",
productName:"Reservation Fee",
productCategory:"Fee",
productQuantity:1, productPrice:5.00)
// Send a Revenue Event with attributes 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)
// Revenue with no product details
[Singular revenue:@"USD" amount:1.99];
// Revenue with product details
[Singular revenue:@"EUR" amount:5.00 productSKU:@"SKU1928375"
productName:@"Reservation Fee"
productCategory:@"Fee"
productQuantity:1
productPrice:5.00];
// Send a Revenue Event with attributes in a dictionary
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:@"100% Organic Cotton Mixed Plaid Flannel Shirt"
forKey:ATTRIBUTE_SNG_ATTR_ITEM_DESCRIPTION];
[dic setValue:@"$69.95" forKey:ATTRIBUTE_SNG_ATTR_ITEM_PRICE];
[dic setValue:@"5 Star" forKey:ATTRIBUTE_SNG_ATTR_RATING];
[dic setValue:@"Flannel Shirt" forKey:ATTRIBUTE_SNG_ATTR_SEARCH_STRING];
[Singular revenue:@"USD" amount:19.99 withAttributes:dic];
customRevenue Method
Send custom revenue events to Singular by specifying the event name, revenue amount, currency code, and any additional transaction attributes. Singular processes these events to track in-app revenue.
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
// Revenue with a custom name and no product details
Singular.customRevenue("MyCustomRevenue", currency:"USD", amount:1.99)
// Revenue with a custom name and product details
Singular.customRevenue("MyCustomRevenue", currency:"EUR", amount:5.00,
productSKU:"SKU1928375",
productName:"Reservation Fee",
productCategory:"Fee",
productQuantity:1,
productPrice:5.00)
// Send a Custom Revenue Event with attributes 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)
// Revenue with a custom name and no product details
[Singular customRevenue:@"MyCustomRevenue" currency:@"USD" amount:1.99];
// Revenue with a custom name and product details
[Singular customRevenue:@"MyCustomRevenue" currency:@"EUR" amount:5.00
productSKU:@"SKU1928375"
productName:@"Reservation Fee"
productCategory:@"Fee"
productQuantity:1
productPrice:5.00];
// Send a Custom Revenue Event with attributes in a dictionary
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:@"100% Organic Cotton Mixed Plaid Flannel Shirt"
forKey:ATTRIBUTE_SNG_ATTR_ITEM_DESCRIPTION];
[dic setValue:@"$69.95" forKey:ATTRIBUTE_SNG_ATTR_ITEM_PRICE];
[dic setValue:@"5 Star" forKey:ATTRIBUTE_SNG_ATTR_RATING];
[dic setValue:@"Flannel Shirt" forKey:ATTRIBUTE_SNG_ATTR_SEARCH_STRING];
[Singular customRevenue:@"MyCustomRevenue" currency:@"USD" amount:44.99 withAttributes:dic];
StoreKit2 Support
If your app uses the StoreKit2 framework for In-App Purchase tracking, the customRevenue method is recommended. The customRevenue method requires you to provide the transaction and product object in jsonRepresentation.
Purchase validation is not supported for StoreKit2
customRevenue Method
Signatures
+ (void)customRevenue:(NSData *)transactionJsonRepresentation productJsonRepresentation:(NSData *)productJsonRepresentation;
+ (void)customRevenue:(NSString *)eventName transactionJsonRepresentation:(NSData *)transactionJsonRepresentation productJsonRepresentation:(NSData *)productJsonRepresentation;
Usage Examples
// Fetch transaction and product from StoreKit2
let transaction = ... // Assume this is a valid StoreKit2 transaction
let product = ... // Assume this is a valid StoreKit2 product
// Custom Revenue using __iap__ event name with transaction and product JSON representations
Singular.customRevenue(
transactionJsonRepresentation: transaction.jsonRepresentation,
productJsonRepresentation: product.jsonRepresentation )
// Custom Revenue with custom event name using transaction and product JSON representations
Singular.customRevenue(
"PaymentSuccess",
transactionJsonRepresentation: transaction.jsonRepresentation,
productJsonRepresentation: product.jsonRepresentation )
}
// Fetch transaction and product from StoreKit2
SKTransaction *transaction = ...; // Assume this is a valid StoreKit2 transaction
SKProduct *product = ...; // Assume this is a valid StoreKit2 product
// Convert transaction and product JSON representations to NSData
NSData *transactionData = [transaction.jsonRepresentation
dataUsingEncoding:NSUTF8StringEncoding];
NSData *productData = [product.jsonRepresentation
dataUsingEncoding:NSUTF8StringEncoding];
// Custom Revenue using transaction and product JSON representations
[Singular customRevenue:transactionData
productJsonRepresentation:productData];
// Custom Revenue with event name using transaction and product JSON representations
[Singular customRevenue:@"PaymentSuccess"
transactionJsonRepresentation:transactionData
productJsonRepresentation:productData];
Hybrid Event Tracking (Advanced)
Singular recommends sending all events and revenue through the Singular SDK integrated into your app. However, Singular can collect events and revenue from other sources.
Any event NOT sent from the Singular SDK must comply with Singular's Server-to-Server Event documentation requirements and provide the matching device identifier to correctly attribute an event.
Important:
Discrepancies will occur if device identifiers used on Server-to-Server event requests do not have a matching device identifier in Singular. Be aware of the following possibilities:
- If an event request is received "before" the Singular SDK has recorded the device identifier, from an App Session, then the event request will be considered the "first session" for the unknown device, and Singular will attribute the device as an organic attribution.
- If the Singular SDK did record a device identifier, but the Singular SDK identifier differs from the device identifier specified in the Server-to-Server Event request then the event will be attributed incorrectly.
Hybrid Event Tracking Guides
Sending Events from an Internal Server
Singular can collect data about revenue from your Server to help analyze the performance and ROI of your campaigns.
Requirements:
- From an in-app Registration or Login Event, capture and pass the device identifiers and store this data with the User ID on your server. Because device identifiers may change for a user, be sure to update the identifiers when a user generates an app session. This guarantees the server-side event will be attributed to the correct device.
- Server-side events are platform specific and should only be sent with the device identifier matching the device platform (e.g., IDFA or IDFV for iOS devices).
- You can use the Singular Internal BI postback mechanism to push an event in real time to your internal endpoint so that you can update the data set on the server side. See the Internal BI Postback FAQ.
- Review the "Tracking Revenue" section in the Server-to-Server Integration guide for details.
Sending Events from a Revenue Provider
Third-party providers like RevenueCat or adapty can provide Purchase and Subscription Revenue to Singular.
Follow the links below for details on how to enable these partners.
Sending Events from Segment
To enable Segment to send events to Singular, in parallel with the Singular SDK, you must add a "Cloud-Mode" Destination in Segment. Follow our guide HERE.