Enable page view signals in an iOS app
The page view signal captures when users open screens in your app, letting marketers segment users and trigger messages based on the screens and categories users have viewed. Use it on screens without a dedicated signal type - such as category pages, product overviews or landing pages linked from email campaigns. For screens like product detail or order confirmation, use the appropriate signal instead.
Availability: Premium and Ultimate
Languages: Swift and Objective-C
Implementation considerations
When to fire the signal
Fire the page view signal after the screen is visible to the user.
Screen naming
Use a consistent naming strategy across your app. Options:
- Class name - use the view controller or view struct name (for example,
"ProductDetailViewController"). Simple and consistent. - Logical name - use a human-readable label (for example,
"Product detail"). More meaningful in analytics but requires maintenance.
Whichever strategy you choose, apply it uniformly so navigation paths are comparable across sessions.
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 |
|---|---|---|
signalType | String | Signal type. Value: "pageView". |
url | String | The screen name or identifier for the screen the user has opened. Screen names are accepted as-is - there is no URL validation. |
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". |
description | String | A description of the signal |
name | String | A label to differentiate this signal from others (for example, "pageView from iOS app"). Max 256 characters |
pageCategory | String | The category the screen belongs to (for example, "clothing", "account") |
Basic example
import Connect
ConnectCustomEvent.sharedInstance().logSignal([
"signalType": "pageView",
"url": "ProductDetailViewController"
])#import <Connect/Connect.h>
[[ConnectCustomEvent sharedInstance] logSignal:@{
@"signalType": @"pageView",
@"url": @"ProductDetailViewController"
}];Complete example
// UIViewController: fire in viewDidLoad() for initial presentation.
// Use viewWillAppear(_:) instead if you also want to capture
// back-navigation returns to the same view controller.
override func viewDidLoad() {
super.viewDidLoad()
// Set up UI ...
ConnectCustomEvent.sharedInstance().logSignal([
"signalType": "pageView",
"url": "ProductDetailViewController"
])
}// Use .onAppear on the root view of the screen.
// This fires each time the view appears, including back-navigation returns.
struct ProductScreen: View {
var body: some View {
ProductContent()
.onAppear {
ConnectCustomEvent.sharedInstance().logSignal([
"signalType": "pageView",
"url": "ProductScreen"
])
}
}
}// UIViewController: fire in viewDidLoad for initial presentation.
// Use viewWillAppear: instead if you also want to capture
// back-navigation returns to the same view controller.
- (void)viewDidLoad {
[super viewDidLoad];
// Set up UI ...
[[ConnectCustomEvent sharedInstance] logSignal:@{
@"signalType": @"pageView",
@"url": @"ProductDetailViewController"
}];
}Best practices
- Use a single naming convention for
urlacross the team. - Attach an
audienceidentifier whenever the user is authenticated. - Avoid firing duplicate signals - check that the signal fires once per screen display, not on every layout pass. In UIKit, prefer
viewDidLoad()overviewWillAppear(_:)for screens where back-navigation returns should not re-fire.
Verification
After navigating to a tracked screen, check the Xcode console for:
[Connect] pageView 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.
Contact not created or updated?
- Verify attribute key names match exactly how they appear in Connect - including capitalization and spacing.
Duplicate signals on the same screen?
- In UIKit, check whether the signal is firing in
viewWillAppear(_:)and the user is navigating back to this screen. Switch toviewDidLoad()if back-navigation returns should not re-fire. - In SwiftUI,
.onAppearfires each time the view appears. Use a@Stateflag if you want to fire only once per view lifecycle.
Related pages
Updated about 1 hour ago
