Product Events
Product events record commerce actions on a product, such as views, add to cart and purchases, and keep product attributes up to date. General rules for events: Sending Events.
Requirements
- A successful
ping()in this installation, see Contacts. - A stable product ID for each product, the same one you use on your website or in your product feed.
Setup
Call sendProductEvent(_:eventType:attributes:_:) when the action happens:
- Swift
- Objective-C
UserSDK.default?.sendProductEvent(
"SKU-1234",
eventType: .addToCart,
attributes: [
"name": "Running Shoes",
"product_url": "https://www.example.com/shoes/1234",
"price": 89.99,
"currency": "USD",
"size": "42"
]
) { success, error in
if !success { print("Product event failed: \(String(describing: error))") }
}
[[UserSDK default] sendProductEventWithProductId:@"SKU-1234"
eventType:EventTypeAddToCart
attributes:@{@"name": @"Running Shoes",
@"product_url": @"https://www.example.com/shoes/1234",
@"price": @89.99, @"currency": @"USD", @"size": @"42"}
completion:nil];
The product event appears on the contact's timeline, and the product in the panel has the attributes you sent (price, currency, size).
Handling
Attributes are product attributes
Each key in attributes is stored as a separate attribute of the product, next to the product ID. Pass the product name as name and the product page URL as product_url. A new value replaces the previous value of that product attribute. Every new key creates a new product attribute, so use a fixed set of keys with stable value types. If a key in attributes is custom_id, the product ID wins.
Values must be JSON values, see Attribute value types. Any other value, for example Date, URL, Data or a Double that is NaN, ends with invalidData and nothing is sent. Before 1.3.0 such values crashed the app.
Before 1.2.0, params were sent nested under custom_data and stored as a single JSON attribute. From 1.2.0 each param is its own product attribute, the same as in the Android SDK. If you built segments or automations on the custom_data attribute, rebuild them on the individual attributes.
Events in quick succession
The event time is sent with one second precision. Two events with the same product, the same event type and the same second are recorded as one event.
Methods
sendProductEvent(_:eventType:attributes:_:)
Queues a product event for the current contact. Added in 1.3.0. The earlier sendProductEvent(_:eventType:name:productURL:params:_:) still works and is deprecated until 2.0: it sends name and productURL as the name and product_url attributes.
| Name | Type | Required | Description |
|---|---|---|---|
productId | String | Yes | Your product ID. Must not be empty. |
eventType | UserSDK.ProductEventType | Yes | The action, see the table below. |
attributes | [String: Any]? | No | Product attributes, for example name, product_url, price. Default nil. |
completion | ((Bool, Error?) -> Void)? | No | Called with the result on the main thread. See Completion thread. |
Returns nothing. Without a contact (no successful ping yet), the completion reports notIdentified and the event is not queued. An empty product ID ends with invalidName without a request.
UserSDK.default?.sendProductEvent("SKU-1234", eventType: .view)
ProductEventType values and how they appear in the panel:
| Swift | Objective-C | Panel |
|---|---|---|
.addToCart | EventTypeAddToCart | add to cart |
.purchase | EventTypePurchase | purchase |
.liking | EventTypeLiking | liking |
.addToObservation | EventTypeAddToObservation | add to observation |
.order | EventTypeOrder | order |
.reservation | EventTypeReservation | reservation |
.return | EventTypeReturn | return |
.view | EventTypeView | view |
.click | EventTypeClick | click |
.detail | EventTypeDetail | detail |
.add | EventTypeAdd | add |
.remove | EventTypeRemove | remove |
.checkout | EventTypeCheckout | checkout |
.checkoutOption | EventTypeCheckoutOption | checkout option |
.refund | EventTypeRefund | refund |
.promoClick | EventTypePromoClick | promo click |
In Swift, EventType is renamed to ProductEventType. EventType still works and is deprecated.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
Completion reports notIdentified ("No user exists yet") | No successful ping yet. | Call ping() first. |
Segments built on custom_data stopped matching after the upgrade | Since 1.2.0 params are separate product attributes. | Rebuild the segments on the individual attributes. |
| The panel shows many similar product attributes | Attributes use changing keys, for example with IDs or dates in the key. | Use a fixed set of keys. Put changing data in values. |
| Two quick events count as one | Same product, type and second. | Expected. Send distinct actions with distinct event types. |