---
title: Track Screens - iOS
description: Learn how to implement screen tracking in your iOS app with CSQ SDK to capture user navigation patterns and screen interactions
lastUpdated: 31 October 2025
source_url:
  html: https://docs.contentsquare.com/en/csq-sdk-ios/experience-analytics/track-screens/
  md: https://docs.contentsquare.com/en/csq-sdk-ios/experience-analytics/track-screens/index.md
---

Contentsquare aggregates user behavior and engagement at the screen level. To do so, it is required to track screen transitions by calling a dedicated API. When the API is called, the SDK logs a `screen_view` event that identifies the new screen with the screen name provided.

Warning

Sessions without at least one screenview will be discarded.

* Swift

  ```swift
  let customVar = CustomVar(index: 123, name: "my_custom_var", value: "some_value")
  CSQ.trackScreenview("MyViewController", cvars: [customVar])
  ```

* Objective-C

  ```objective-c
  CSQCustomVar *customVar = [[CSQCustomVar alloc] initWithIndex:123 stringName:@"my_custom_var" stringValue:@"some_value"];
  [CSQ trackScreenview:@"MyViewController" cvars:@[customVar]];
  ```

## Screen name handling

The screen name is limited to 2083 characters. However, this limit is not enforced by the SDK, but rather by the Contentsquare servers.

Note

If the Track screen API is called without passing a screen name, the event will still be processed with default value: `missing screenName ([ViewController className])`

Warning

**Note about Privacy Manifest:** If you decide to use Screen names to collect new data or use already collected data but for a different purpose, it is up to you to update the privacy practices described in your app manifest accordingly. See [Purpose of processing and categories of personal data collected](../privacy/#purpose-of-processing-and-categories-of-personal-data-collected) already described in the Contentsquare iOS SDK Privacy Manifest.

## Screenview after app in background

The SDK triggers a screenview automatically after the app is put in background and foreground, as long as a screenview with a screen name has been triggered previously. It will use the last screen name set.

## Implementation recommendations

From a functional standpoint, we expect a screenview to be sent:

* Right after the SDK has started
* When the screen appears
* When a modal/pop-up is closed and the user is back on the screen
* When the app is put in the foreground (after an app hide)

We advise you to take a look at our reference implementations of screenviews in [our sample app ↗](https://github.com/ContentSquare/apple-sample-app). Learning from them is the best way to make sure your implementations are correct. Regardless, here is some general advice.

### When to send your first screenview

Most events collected by the SDK require a screenview event to be sent first so they can be associated with that screen; otherwise, they will be discarded. If you need to collect events from the moment the app launches, you should trigger a screenview event immediately after the SDK has started:

* Swift

  ```swift
  CSQ.start()
  CSQ.trackScreenview("Launch screen")
  ```

* Objective-C

  ```objective-c
  [CSQ start];
  [CSQ trackScreenview:@"Launch screen"];
  ```

#### UIKit

As a general rule of thumb, you should send your screenviews in `viewWillAppear(_ animate: Bool)`. Be aware that only doing this might not cover all your cases though, and you might need to send screenview events in other parts of your code.

#### SwiftUI

If you are using SwiftUI to build your application, you should send your screenview in `.onAppear()`. Be aware that only doing this might not cover all your cases though, and you might need to send screenview events in other parts of your code.

```swift
import ContentsquareSQK


var body: some View {
    Text("My first screen")
        .foregroundColor(Color.blue)
    .onAppear() {
        CSQ.trackScreenview("First screenView")
    }
}
```

### ScrollViews with paging

Be careful when tagging screens with paged ScrollViews: if you want to create a screenview event whenever the user changes the page, do so in UIScrollViewDelegate's `scrollViewDidEndDecelerating(_ scrollView: UIScrollView)` function. Make sure that you do not trigger a double tag when the screen appears, or when you come back to the screen after the app being hidden. Also make sure not to send a screenview when the user slightly interacts with a page, but without really changing pages.

### Popups and modals

When dealing with popups and modals, if you are having issues triggering a screenview event for the underlying view when the modal closes we have the following advice. You could overcome this issue by using a delegate pattern, and setting the underlying screen as the modal's delegate. The modal would call some delegate method when it is dismissed. The underlying screen would implement that method, where it would make the screenview.

iOS 13 and later

On iOS 13 and more, modals can be dismissed by swiping down.\
In that case, `unwindFromSegue` won't be triggered.

The new `presentationControllerDidDismiss(_ presentationController:)` function of `UIAdaptivePresentationControllerDelegate` will be triggered instead.

Implement this function and call `CSQ.trackScreenview(screenViewWithName:)` there for the tracking to be correct on all iOS versions.

[Check out our sample app ↗](https://github.com/ContentSquare/apple-sample-app/blob/master/Shared/Showcases/Screen%20Views/Modals/ModalPresentingViewController.swift) for more details about the implementation.

### Back navigation and navigation between screens

Make sure that screenview events will be triggered when a user will go to the previous screen (example: Home → Profile → Home), it is expected to have a screenview event for the Home screen that might be reached with the back navigation button. Normally, if you send your screenviews in `viewWillAppear`, this should work fine.

### Redirecting the user to another screen (authentication, home) when closing the app/re-opening the app

For some apps, you might want to redirect users whenever they hide your app, for example for security purposes (bank apps, password managers, etc...). If that is the case, pay specific attention to the way screenview events are sent, in order not to track a screen which is not actually shown users.

### Application life cycle

When your application returns from the background to the foreground, the SDK automatically logs a screenview with the title of the last logged screenview, so you don't have to handle this transition yourself.

## How to name screens

As a general rule, keep the number of distinct screen names under 100. Since these names are used to map your app in Contentsquare, choose names that are clear and comprehensive.

### Separate words with spaces, dashes or underscores

When generating screen names with multiple words, separate them using spaces, dashes, or underscores.

For instance, use `Home & Living - Home Furnishings` instead of ~~`homeLivingHomeFurnishings`~~ for a sub-category in a retail app.

Casing sensitivity

Screen names are not case sensitive and will appear in lowercase on the Contentsquare platform.

```swift
CSQ.trackScreenview("ScreenName") // screenname
CSQ.trackScreenview("Screen Name") // screen name
CSQ.trackScreenview("screen_name") // screen_name
CSQ.trackScreenview("screenname") // screenname
```

### Use screen template/layout names

As a general recommendation, use names referring to the screen template/layout rather than referring to the specific content (data). This will help:

* To keep the number of distinct screen names low and therefore make Contentsquare easier to use
* Remove the risk of sending Personal Data to Contentsquare

List of screen types falling into that category: *Product detail, Event detail, Conversation/Chat, User profile...*

### Screens with multiple states/layouts

Screens can have different layouts or states depending on the user context. In this case, append its value to the screen name.

**Home screen**

| State | Screen name |
| - | - |
| App landing layout | `Home` |
| Women products layout | `Home - Women` |
| Men products layout | `Home - Men` |
| Sales layout | `Home - Sales` |

**Product Detail screen (PDP)**

| State | Screen name |
| - | - |
| Users on a Top for Women PDP | `PDP - Clothing - Women - Tops` |
| Users on a Microwave PDP | `PDP - Kitchenware - Electrics - Microwave` |
| Users on a Hotel details screen | `PDP - Holiday type - Season - Board` |

**User account screen**

| State | Screen name |
| - | - |
| Overview | `My Account - Dashboard` |
| Order history | `My Account - Order history` |
| Returns | `My Account - Returns` |

**Search screen**

| State | Screen name |
| - | - |
| Search | `Search` |
| Search results for "Skincare" products | `Search - Skincare` |
| Search results error screen | `Search - Error` |

**Cart screen**

| State | Screen name |
| - | - |
| Empty cart | `Cart - Empty` |
| Items have been added to the cart | `Cart - Populated` |
| Issues with availability or pricing | `Cart - Error` |

**Checkout screen**

| State | Screen name |
| - | - |
| User provides name, surname, and date of birth | `Checkout - User Details` |
| User provides shipping address | `Checkout - Shipping Details` |
| User inputs their credit card information | `Checkout - Payment` |
