Enable order signals in an iOS app
The order signal captures when a user completes a transaction in your app - for example, a retail purchase, a flight booking or an insurance application. It is essential for tracking conversions and triggering post-purchase campaigns. In Connect, the signal enables segmentation by order ID, value, product and product category.
Availability: Pro, Premium and Ultimate
Languages: Swift and Objective-C
Implementation considerations
When to fire the signal
Fire the order signal after the order is confirmed by your backend, not when the user taps the purchase button. At that point you have the order ID and all the data needed to populate the signal fields. If your success flow clears the cart, capture the line items before doing so - the item data needed for orderedItems will no longer be available after the cart is cleared.
Ordered items
Each item in the order is represented as a [String: Any] dictionary inside an array. Pass the array as the value of orderedItems in the signal dictionary. If orderedItems fails validation - for example, due to a missing required item field - the entire signal is discarded.
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 order-level fields as a flat [String: Any] dictionary. Pass orderedItems as an array of item dictionaries.
- (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 order-level fields as an NSDictionary. Pass orderedItems as an NSArray of item dictionaries.
Signal fields
Order-level required
| Field | Type | Description |
|---|---|---|
orderId | String | Unique order identifier returned by your backend |
signalType | String | Signal type. Value: "order". |
Order-level 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 |
name | String | A label to differentiate this signal from others (for example, "order from iOS app"). Max 256 characters |
orderDiscount | Number | Total discount applied to the order |
orderedItems | [[String: Any]] | Array of ordered items. Each item is a [String: Any] dictionary - see item-level fields below. |
orderShippingHandling | Number | Shipping and handling cost |
orderSubtotal | Number | Subtotal amount before tax and shipping |
orderTax | Number | Tax amount |
orderValue | Number | Total order value including tax and shipping |
Item-level required
| Field | Type | Description |
|---|---|---|
itemQuantity | Number | Quantity of this product purchased |
productId | String | Unique product identifier (may match SKU) |
productName | String | Name of the product |
unitPrice | Number | Price the customer paid for one unit |
Item-level optional
| Field | Type | Description |
|---|---|---|
discount | Number | Discount amount per unit |
productCategory | String | Product category from your catalog |
productDescription | String | Description of the product |
promotionId | String | ID from a marketing campaign that influenced the purchase |
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).Pass
orderedItemsas a[[String: Any]]array. IforderedItemsfails validation, the entire signal is discarded.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
let item: [String: Any] = [
"productId": "SKU-12345",
"productName": "Wireless Headphones",
"itemQuantity": 1,
"unitPrice": 299.99
]
ConnectCustomEvent.sharedInstance().logSignal([
"signalType": "order",
"orderId": "ORD-98765",
"orderValue": 299.99,
"currency": "USD",
"orderedItems": [item]
])#import <Connect/Connect.h>
NSDictionary *item = @{
@"productId": @"SKU-12345",
@"productName": @"Wireless Headphones",
@"itemQuantity": @1,
@"unitPrice": @299.99
};
[[ConnectCustomEvent sharedInstance] logSignal:@{
@"signalType": @"order",
@"orderId": @"ORD-98765",
@"orderValue": @299.99,
@"currency": @"USD",
@"orderedItems": @[item]
}];Complete example
This example fires an order signal from the confirmation screen after the backend confirms the order. It includes multiple ordered items, order totals and optional contact mapping.
import Connect
private func sendOrderSignal(orderId: String, items: [CartLineItem], total: NSDecimalNumber) {
// Build ordered items - one dictionary per line item
let orderedItems: [[String: Any]] = items.map { item in
var orderedItem: [String: Any] = [
"productId": item.product.id,
"productName": item.product.name,
"itemQuantity": item.quantity,
"unitPrice": item.product.price.doubleValue,
"productCategory": item.product.categoryName,
"currency": "USD"
]
return orderedItem
}
var signal: [String: Any] = [
"signalType": "order",
"orderId": orderId,
"orderValue": total.doubleValue,
"currency": "USD",
"orderedItems": orderedItems
]
var audience: [String: Any] = [:]
if let email = UserSession.shared.email {
audience["Email Address"] = email
}
if !audience.isEmpty {
signal["audience"] = audience
}
let accepted = ConnectCustomEvent.sharedInstance().logSignal(signal)
NSLog("[Connect] order signal accepted: \(accepted)")
}#import <Connect/Connect.h>
- (void)sendOrderSignalWithOrderId:(NSString *)orderId
items:(NSArray *)items
total:(NSDecimalNumber *)total {
NSMutableArray *orderedItems = [NSMutableArray array];
for (CartLineItem *item in items) {
[orderedItems addObject:@{
@"productId": item.product.id,
@"productName": item.product.name,
@"itemQuantity": @(item.quantity),
@"unitPrice": @(item.product.price.doubleValue),
@"productCategory": item.product.categoryName,
@"currency": @"USD"
}];
}
NSMutableDictionary *signal = [@{
@"signalType": @"order",
@"orderId": orderId,
@"orderValue": @(total.doubleValue),
@"currency": @"USD",
@"orderedItems": orderedItems
} mutableCopy];
NSMutableDictionary *audience = [NSMutableDictionary dictionary];
if ([[UserSession shared] email]) {
audience[@"Email Address"] = [[UserSession shared] email];
}
if (audience.count > 0) {
signal[@"audience"] = audience;
}
BOOL accepted = [[ConnectCustomEvent sharedInstance] logSignal:signal];
NSLog(@"[Connect] order signal accepted: %@", accepted ? @"true" : @"false");
}Call the method before clearing the cart - once the cart is cleared, the line item data is no longer available.
Verification
After running the app and completing checkout, check the Xcode console for:
[Connect] order 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. Confirm orderId and orderedItems match the values from the completed order.
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 the required order-level fields are present:
signalTypeandorderId. - Confirm each item in
orderedItemshas all required fields:productId,productName,itemQuantity,unitPrice.
Contact not created or updated?
- Verify attribute key names in
audiencematch exactly how they appear in Connect - including capitalization and spacing.
Order items missing from the signal?
- Confirm
orderedItemsis populated before the cart is cleared. - Check that the array is not empty - an empty
orderedItemsarray may be treated as invalid.
Related pages
Updated about 1 hour ago
