Enable product view signals in an iOS app

The product view signal captures when a user views a product detail screen and tells marketers which products each contact is interested in, enabling segmentation by product and product category in Connect. The product can be physical, digital or a service like a tour or insurance package.

Availability: Premium and Ultimate

Languages: Swift and Objective-C


Implementation considerations

When to fire the signal

Fire the product view signal in viewDidLoad() once the product data is available. Use productView instead of pageView on product detail screens - productView carries the richer schema and is the semantically correct signal type for this context.

If your app shows multiple products simultaneously - for example, a shortlist of hotel rooms - fire one signal per product.

Relationship to the product configuration signal

The product view and product configuration signals work together:

  • productView - captures the product itself when the screen loads
  • productConfiguration - captures user interactions on the product screen, such as selecting a color or size

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]?) -> Bool

Sends 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.

Signal fields

Required

FieldTypeDescription
productIdStringUnique product identifier (may match SKU)
productNameStringName of the product
signalTypeStringSignal type. Value: "productView".

Optional

FieldTypeDescription
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.
availabilityStringAvailability status (for example, "In Stock", "Out of Stock", "Back Order")
brandNameStringBrand name of the product
categoryStringSignal category. Value: "Behavior".
currencyStringISO 4217 currency code (for example, "USD", "EUR"). Defaults to the currency set for your Connect subscription.
descriptionStringA description of the signal
discountNumberDiscount amount or difference between original and current price
effectStringDescribes the effect of the signal on engagement. Use "positive" for product views.
imageUrls[String]URLs of product images
inventoryQuantityNumberNumber of units available
modelStringModel number or description
msrpNumberSuggested retail price or original price
nameStringA label to differentiate this signal from others (for example, "productView from iOS app"). Max 256 characters
productCategoryStringProduct category from your catalog
productDescriptionStringDescription of the product
productRatingNumberRating of the product
productStatusStringCurrent lifecycle state (for example, "Active", "Discontinued", "Upcoming")
productUrls[String]URLs of product pages
promotionIdStringID from a marketing campaign that led to this view
shoppingCartUrlStringURL or deep link to the shopping cart
skuStringSKU, if different from productId
unitPriceNumberUnit price of the product
virtualCategoryStringCategory based on navigation path (for example, "New arrivals", "Sale")

Things to know

  • Number fields accept native Swift numeric types (Int, Double, NSDecimalNumber).

  • Pass imageUrls and productUrls as [String] arrays.

  • 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": "productView",
    "productId": "SKU-12345",
    "productName": "Wireless Headphones"
])
#import <Connect/Connect.h>

[[ConnectCustomEvent sharedInstance] logSignal:@{
    @"signalType": @"productView",
    @"productId": @"SKU-12345",
    @"productName": @"Wireless Headphones"
}];

Complete example

This example fires a product view signal from a product detail screen when it loads. It includes pricing, category and optional contact mapping.

import Connect

override func viewDidLoad() {
    super.viewDidLoad()
    // Set up UI ...

    var signal: [String: Any] = [
        "signalType": "productView",
        "productId": product.id,
        "productName": product.name,
        "unitPrice": product.price.doubleValue,
        "productCategory": product.categoryName,
        "currency": "USD",
        "effect": "positive"
    ]

    if UserSession.shared.isAuthenticated, let email = UserSession.shared.email {
        signal["audience"] = ["Email Address": email]
    }

    let accepted = ConnectCustomEvent.sharedInstance().logSignal(signal)
    NSLog("[Connect] productView signal accepted: \(accepted)")
}

Verification

After running the app and opening a product detail screen, check the Xcode console for:

[Connect] productView 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). A false return indicates the SDK rejected the call.
  • Verify the appKey and postURL match the Connect org you're checking.

Signal marked as invalid in Connect?

  • Confirm all required fields are present: signalType, productId, productName.

Contact not created or updated?

  • Verify attribute key names in audience match exactly how they appear in Connect - including capitalization and spacing.

Related pages


Did this page help you?