Enable add-to-cart signals in an iOS app
The add-to-cart signal captures when a user adds an item to their cart or selection - for example, a product, a flight or a hotel room. It helps track shopping behavior across your app and can be used for product recommendations, behavioral analytics and targeted segmentation by product and product category in Connect.
Availability: Pro, Premium and Ultimate
Languages: Swift and Objective-C
Implementation considerations
When to fire the signal
Decide when to send the signal based on your app's behavior:
- On button tap - fire immediately when the user taps Add to cart. Best for tracking intent, even if the action fails (for example, due to a network error).
- After cart update - fire after confirming the item was successfully added. Ensures accuracy but may miss failed attempts.
For most implementations, firing on tap is recommended.
Multiple purchasing flows
Your app may have more than one path to add a product to the cart:
- Product detail screen
- Product listing (quick add)
- Product sheet or modal
Each flow may need separate signal calls if product data is structured differently. Make sure all flows are covered.
Contact mapping
Include the audience field to attribute this signal to a contact in Connect. See How behavior signals update Connect data for identifier formats and contact resolution details.
Configuration
Before adding behavior signals, integrate the Connect SDK into your app. See the guide for your development language: Swift or Objective-C.
Method
func logSignal(_ data: [String: Any]?) -> BoolSends the signal to the Acoustic Connect endpoint. Initialize the Connect SDK before calling this method using ConnectSDK.shared.enable(with:).
Pass all fields as a flat [String: Any] dictionary. The SDK handles the signal structure automatically. You do not need to construct a nested object.
- (BOOL)logSignal:(NSDictionary *)values;Sends the signal to the Acoustic Connect endpoint. Initialize the Connect SDK before calling this method using [[ConnectApplicationHelper sharedInstance] enableFramework:withPostMessageUrl:].
Pass all fields as an NSDictionary. The SDK handles the signal structure automatically. You do not need to construct a nested object.
Signal fields
Required
| Field | Type | Description |
|---|---|---|
itemQuantity | Number | Quantity of items added to the cart |
productId | String | Unique product identifier (may match SKU) |
productName | String | Name of the product |
signalType | String | Signal type. Value: "addToCart". |
unitPrice | Number | Unit price of the product |
Optional
| Field | Type | Description |
|---|---|---|
audience | [String: Any] | Key-value pairs for contact mapping. Keys must match contact attribute names exactly as they appear in Connect, including capitalization and spacing. |
category | String | Signal category. Value: "Behavior". |
currency | String | ISO 4217 currency code (for example, "USD", "EUR"). Defaults to the currency set for your Connect subscription. |
description | String | A description of the signal |
discount | Number | Discount amount applied to the item |
name | String | A label to differentiate this signal from others (for example, "addToCart from product detail"). Max 256 characters |
productCategory | String | Product category from your catalog (useful for segmentation) |
productDescription | String | Description of the product |
promotionId | String | ID from a marketing campaign that led to this action |
shoppingCartUrl | String | URL or deep link to the shopping cart |
virtualCategory | String | Category based on navigation path (for example, "New arrivals", "Sale") |
Things to know
Number fields accept native Swift numeric types (
Int,Double,NSDecimalNumber).If a required field is missing or invalid, the entire signal is discarded. For fields that don't apply to your business, use a placeholder value.
Basic example
import Connect
ConnectCustomEvent.sharedInstance().logSignal([
"signalType": "addToCart",
"productId": "SKU-12345",
"productName": "Wireless Headphones",
"itemQuantity": 1,
"unitPrice": 299.99
])#import <Connect/Connect.h>
[[ConnectCustomEvent sharedInstance] logSignal:@{
@"signalType": @"addToCart",
@"productId": @"SKU-12345",
@"productName": @"Wireless Headphones",
@"itemQuantity": @1,
@"unitPrice": @299.99
}];Complete example
This example fires an add-to-cart signal from a product detail view controller after updating the cart, with dynamic product data and optional contact mapping.
import Connect
@objc private func addToCart() {
let qty = Int(quantityStepper.value)
CartStore.shared.add(product: product, colorway: selectedColorway, quantity: qty)
var signal: [String: Any] = [
"signalType": "addToCart",
"productId": product.id,
"productName": product.name,
"itemQuantity": qty,
"unitPrice": product.price.doubleValue,
"productCategory": product.categoryName,
"currency": "USD"
]
if UserSession.shared.isAuthenticated, let email = UserSession.shared.email {
signal["audience"] = ["Email Address": email]
}
let accepted = ConnectCustomEvent.sharedInstance().logSignal(signal)
NSLog("[Connect] addToCart signal accepted: \(accepted)")
}#import <Connect/Connect.h>
- (void)addToCart {
NSInteger qty = (NSInteger)self.quantityStepper.value;
[CartStore.shared addProduct:self.product colorway:self.selectedColorway quantity:qty];
NSMutableDictionary *signal = [@{
@"signalType": @"addToCart",
@"productId": self.product.id,
@"productName": self.product.name,
@"itemQuantity": @(qty),
@"unitPrice": @(self.product.price.doubleValue),
@"productCategory": self.product.categoryName,
@"currency": @"USD"
} mutableCopy];
if ([[UserSession shared] isAuthenticated] && [[UserSession shared] email]) {
signal[@"audience"] = @{ @"Email Address": [[UserSession shared] email] };
}
BOOL accepted = [[ConnectCustomEvent sharedInstance] logSignal:signal];
NSLog(@"[Connect] addToCart signal accepted: %@", accepted ? @"true" : @"false");
}Verification
After running the app and adding some products to your cart, check the Xcode console for:
[Connect] addToCart signal accepted: true
The false value means the SDK rejected the call - see Troubleshooting below. Once the console confirms acceptance, verify the signal is available in Connect.
Troubleshooting
Signal not appearing in Connect?
- Confirm the Connect SDK is initialized before any signal calls. See Method.
- Capture the return value and check that it is
true:let accepted = ConnectCustomEvent.sharedInstance().logSignal(signal). Afalsereturn indicates the SDK rejected the call. - Verify the
appKeyandpostURLmatch the Connect org you're checking.
Signal marked as invalid in Connect?
Confirm all required fields are present: signalType, productId, productName, itemQuantity, unitPrice.
Contact not created or updated?
Verify attribute key names in audience match exactly how they appear in Connect - including capitalization and spacing.
Related pages
Updated about 1 hour ago
