> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpanel.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mixpanel SDKs: iOS (Swift)

## Getting Started

Please refer to our [Quickstart Guide](/docs/quickstart/connect-your-data?sdk=swift).

The [Full API Reference](https://mixpanel.github.io/mixpanel-swift/), [Library Source Code](https://github.com/mixpanel/mixpanel-swift), and an [Example Application](https://github.com/mixpanel/mixpanel-swift/tree/master/MixpanelDemo/MixpanelDemo) are documented in our GitHub repo.

## Installing the Library

You can install the Swift library by using CocoaPods, Carthage, or Swift Package Manager.

<Tabs>
  <Tab title="Swift Package Manager">
    1. In Xcode, select File > Add Packages...

    2. Enter the package URL for [this repository](https://github.com/mixpanel/mixpanel-swift) and select version v2.8.0 or above.
  </Tab>

  <Tab title="CocoaPods">
    1. Install CocoaPods by typing the following in your command line:

    ```bash theme={"system"}
    # install CocoaPods
    gem install cocoapods
    ```

    2. After installing CocoaPods, create a local CocoaPods spec mirror by running the following:

    ```bash theme={"system"}
    # Create CocoaPods spec mirror
    pod setup
    ```

    3. Then navigate to your Xcode project directory and create a Podfile by running the following:

    ```bash theme={"system"}
    # create Podfile in project directory
    pod init
    ```

    4. Open the Podfile that was generated and add the Mixpanel library to your dependencies:

    ```ruby Ruby theme={"system"}
    target 'MyApp' do
      pod 'Mixpanel-swift'
    end
    ```

    5. Install the Mixpanel library and create a new Xcode workspace by running the following in the Xcode project directory:

    ```bash theme={"system"}
    // install library in your dependencies
    pod install
    ```
  </Tab>

  <Tab title="Carthage">
    Mixpanel supports [Carthage](https://github.com/Carthage/Carthage#quick-start) to package your dependencies as a framework. Include the following dependency in your Cartfile:

    ```bash theme={"system"}
    # add Mixpanel library to your dependencies
    github "mixpanel/mixpanel-swift"
    ```
  </Tab>
</Tabs>

After installing the library, import `Mixpanel` into `AppDelegate.swift` and initialize Mixpanel within [`application:didFinishLaunchingWithOptions:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application) using your [project token](/docs/orgs-and-projects/managing-projects#find-your-project-tokens).

```swift Swift theme={"system"}
/// import Mixpanel class from the library
import Mixpanel

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    ...
    /// initialize Mixpanel using your project token
    let options = MixpanelOptions(token: "YOUR_PROJECT_TOKEN")
    Mixpanel.initialize(options: options)
    ...
}
```

<span id="library-configuration" />

### SDK Configuration Using MixpanelOptions

<Warning>
  **Data Residency:** For projects with EU or India data residency, you must configure the SDK to use the correct [regional endpoint](#data-residency).
  Events sent to the wrong region will not be ingested. Learn more about [Privacy-Friendly Tracking](/docs/tracking-methods/sdks/swift#privacy-friendly-tracking)
</Warning>

Configure the Mixpanel SDK using [`MixpanelOptions`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) to customize tracking behavior, data residency, privacy settings, and more.

#### Configuration Reference

| Config Option                | Description                                                                                                                                                               | Default                              |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `token`                      | Your Mixpanel project token (required)                                                                                                                                    | N/A                                  |
| `serverURL`                  | Custom API endpoint. **Required** for [EU](#eu-data-residency) or [India](#india-data-residency) data residency. Takes precedence over `proxyServerConfig.serverUrl`      | US (`https://api.mixpanel.com`)      |
| `flushInterval`              | Interval in seconds between automatic flush operations. Set to `0` to disable. See [Flushing Events](#flushing-events)                                                    | `60`                                 |
| `trackAutomaticEvents`       | Auto-track app lifecycle events. **Not recommended** — see [Legacy Automatically Tracked Events](#legacy-automatically-tracked-events)                                    | `false`                              |
| `optOutTrackingByDefault`    | Start with tracking disabled for GDPR compliance. See [Opt Out of Tracking](#opt-out-of-tracking)                                                                         | `false`                              |
| `useIPAddressForGeoLocation` | Enable IP-based geolocation. See [Disable Geolocation](#disable-geolocation)                                                                                              | `true`                               |
| `useUniqueDistinctId`        | Use device IDFV instead of random UUID. See [Custom Device ID Generation](#custom-device-id-generation)                                                                   | `false`                              |
| `instanceName`               | Unique identifier for multi-instance setups                                                                                                                               | Project token                        |
| `deviceIdProvider`           | Custom closure for device ID generation (requires v5.2.0+). See [Custom Device ID Generation](#custom-device-id-generation)                                               | `nil`                                |
| `superProperties`            | Properties automatically added to all events. Can also be set at runtime. See [Setting Super Properties](#setting-super-properties)                                       | `nil`                                |
| `featureFlagOptions`         | Feature flags configuration (prefetch behavior and custom context). See [Feature Flags Initialization](/docs/tracking-methods/sdks/swift/swift-flags#flag-initialization) | `FeatureFlagOptions(enabled: false)` |
| `proxyServerConfig`          | Proxy configuration with headers and query params                                                                                                                         | `nil`                                |
| `useGzipCompression`         | Enable gzip compression for network requests                                                                                                                              | `true`                               |

<Note>
  **Best Practice:** Configure all settings (especially `serverURL` for data residency) during initialization using `MixpanelOptions`. This ensures all SDK components (events, profiles, feature flags) use the correct configuration from the start, avoiding potential race conditions.
</Note>

After initialization, you can further customize the instance using methods on [`MixpanelInstance`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html).

**Common Configuration Example**

```swift Swift theme={"system"}
import Mixpanel

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    ...
    /// Configure Mixpanel for EU data residency
    let options = MixpanelOptions(
        token: "YOUR_PROJECT_TOKEN",
        serverURL: "https://api-eu.mixpanel.com",
        flushInterval: 15
    )
    Mixpanel.initialize(options: options)

    /// Enable debug logging after initialization
    Mixpanel.mainInstance().loggingEnabled = true
    ...
}
```

See detailed explanations of each option in the sections below.

## Sending Events

Use [`.track(event:properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC5track5event10propertiesySSSg_SDySSAA0A4Type_pGSgtF) to send an event by providing the event name and any event properties. This will trigger a request to the [/track API endpoint](/reference/track-event) to ingest the event into your project.

<Note>
  The [/track endpoint](/reference/track-event) will only validate events with timestamps within the last 5 days of the request. Events with timestamps older than 5 days will not be ingested. See below on best practices for historical imports.
</Note>

**Example Usage**

```swift Swift theme={"system"}
/// track "some_event" 
/// with "plan" event prop set to "Premium"
Mixpanel.mainInstance().track(event: "some_event",
    properties:["Plan": "Premium"])
```

### Timing Events

You can track the time it took for an action to occur, such as an image upload or a comment post, using [`.time(event:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:FC8Mixpanel16MixpanelInstance4timeFT5eventSS_T_). This will mark the "start" of your action, which you can then finish with a track call. The time duration is then recorded in the "Duration" property.

```swift Swift theme={"system"}
/// start the timer for the event "Image Upload"
Mixpanel.mainInstance().time(event: "Image Upload")

/// 20 seconds later...

/// track "Image Upload" event with "Duration" event prop set to 20
Mixpanel.mainInstance().track(event: "Image Upload")
```

### Flushing Events

To preserve battery life and customer bandwidth, the Mixpanel library doesn't send the events you record immediately. Instead, it sends batches to the Mixpanel servers every 60 seconds while your application is running, as well as when the application transitions to the background.

Call [`.flush()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC5flush16performFullFlush10completionySb_yycSgtF) manually if you want to force a flush at a particular moment.

**Example Usage**

```swift Swift theme={"system"}
/// flush batched events for ingestion immediately
Mixpanel.mainInstance().flush()
```

#### Configuring Flush Interval

The default flush interval is 60 seconds. You can customize this using the [`flushInterval`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option in `MixpanelOptions` (see [Configuration Reference](#configuration-reference)). Set to `0` to disable automatic flushing entirely (requires manual `.flush()` calls).

**Recommended: Configure During Initialization**

```swift Swift theme={"system"}
/// Set flush interval to 120 seconds during initialization
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    flushInterval: 120  // Flush every 2 minutes
)
Mixpanel.initialize(options: options)
```

**Alternative: Update After Initialization**
You can also update the flush interval dynamically using [`flushInterval`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC13flushIntervalSdvp).

```swift Swift theme={"system"}
/// Change flush interval at runtime
Mixpanel.mainInstance().flushInterval = 120
```

#### Importing Historical Events

The Swift SDK is a tracking SDK designed for real-time tracking in a client-side environment. Calling [`.track(event:properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC5track5event10propertiesySSSg_SDySSAA0A4Type_pGSgtF) triggers a request to our [/track API endpoint](/reference/track-event), which will validate for events with a timestamp that is within the last 5 days of the request. **Events older than 5 days will not be ingested**.

For bulk import of historical events older than 5 days, we will need to use the [/import API endpoint](/reference/import-events) which is optimized for scripting and supports ingesting historical data. We recommend the [Python SDK](/docs/tracking-methods/sdks/python) (see the [`.import_data()`](https://mixpanel.github.io/mixpanel-python/#primary-interface) function) and [mixpanel-utils module](https://github.com/mixpanel/mixpanel-utils) (see the [`import_events()`](https://github.com/mixpanel/mixpanel-utils?tab=readme-ov-file#import-events) function) which both leverages the /import API for event ingestion.

## Setting Super Properties

Super properties are global event properties that you define once and apply to all events. You can set super properties during SDK initialization or at runtime.

### Setting Super Properties During Initialization

You can set initial super properties using the [`superProperties`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option in `MixpanelOptions` (see [Configuration Reference](#configuration-reference)).

**Example Usage**

```swift Swift theme={"system"}
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    superProperties: [
        "app_version": "1.2.3",
        "platform": "iOS"
    ]
)
Mixpanel.initialize(options: options)

/// track "some_event"
/// "app_version" and "platform" are automatically added as event props
Mixpanel.mainInstance().track(event: "some_event")
```

### Setting Super Properties at Runtime

To register super properties at runtime, call [`.registerSuperProperties(_:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC23registerSuperPropertiesyySDySSAA0A4Type_pGF).

Use [`.registerSuperPropertiesOnce(_:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC27registerSuperPropertiesOnce_12defaultValueySDySSAA0A4Type_pG_AaF_pSgtF) to register super properties without overwriting existing values.

**Example Usage**

```swift Swift theme={"system"}
/// register a "name" super property
Mixpanel.mainInstance().registerSuperProperties(["name": "Sam"])

/// track "some_event"
/// "name" is automatically added as an event prop
Mixpanel.mainInstance().track(event: "some_event")
```

**Best Practice: Batch Multiple Properties**

Creating properties involves an async operation to local storage. If you need to create multiple properties at once, it's best to send a single call to the register function with all properties at once, to avoid possible issues with race conditions overwriting each other.

**Example Usage**

```swift Swift theme={"system"}
Mixpanel.mainInstance().registerSuperProperties([
    "superProp0": "value1",
    "superProp1": "value2",
    "superProp2": "value3",
    "superProp3": 1,
    "superProp4": 2,
    "superProp5": 3
])

Mixpanel.mainInstance().track(event: "test")
```

See more methods related to super properties in the complete library reference [here](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html).

## Managing User Identity

You can handle the identity of a user using the [`.identify()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC8identify10distinctId9usePeople10completionySS_SbyycSgtF) and [`.reset()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC5reset10completionyyycSg_tF) methods. Learn more about [identity management](/docs/tracking-methods/id-management/identity-management) and [identifying users](/docs/tracking-methods/id-management/identifying-users).

### Identify

<Warning>
  We recommend against calling `.identify()` for anonymous visitors to your site.
</Warning>

Call [`.identify()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC8identify10distinctId9usePeople10completionySS_SbyycSgtF) when you know the identity of the current user, passing in their user ID as an argument. This is typically at account registration and at log in.

```swift Swift theme={"system"}
/// your user signs in and tracks a sign in event
Mixpanel.mainInstance().track(event: "sign in")

/// upon sign in, identify the user with their ID
/// ensure future events sent from the user have distinct_id 12345
Mixpanel.mainInstance().identify(distinctId: "12345");
```

### Call Reset on Logout

Call [`.reset()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC5reset10completionyyycSg_tF) to clear data attributed to a user when they logout. This will clear the local storage and allows you to handle [multiple users on a single device](/docs/tracking-methods/id-management/identifying-users-simplified#multiple-users-one-device).

**Example Usage**

```swift Swift theme={"system"}
/// your user signs out and tracks a log out event
Mixpanel.mainInstance().track(event: "log out")

/// upon logout, call reset to clear local storage
/// new distinct_id is generated for events moving forward
Mixpanel.mainInstance().reset()
```

<Note>
  Since v2.7.7, Mixpanel stopped using the IFA (ID for Advertisers) as a distinct\_id. Calls to `.reset()` will generate a new random UUID unless you've configured custom device ID behavior. See [Custom Device ID Generation](#custom-device-id-generation) for details on using IDFV or implementing custom device ID logic.
</Note>

### Custom Device ID Generation

The Swift SDK provides two ways to customize device ID generation (see [Configuration Reference](#configuration-reference)):

1. **`useUniqueDistinctId`** - Use device IDFV (Identifier for Vendor) instead of random UUID
2. **`deviceIdProvider`** - Custom closure for implementing your own device ID generation logic

<Warning>
  Customizing device ID generation is an architectural decision that should be made at project inception. Changing this after deployment can cause user identity management issues.
</Warning>

#### Using Device IDFV

Set [`useUniqueDistinctId`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) to `true` to use the device's IDFV instead of a random UUID. The IDFV persists across app updates but changes when the app is uninstalled and reinstalled.

**Example Usage**

```swift Swift theme={"system"}
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    useUniqueDistinctId: true  // Use IDFV instead of UUID
)
Mixpanel.initialize(options: options)
```

<Note>
  You can also enable IDFV by setting `MIXPANEL_UNIQUE_DISTINCT_ID` in build settings `Active Compilation Conditions` on the Mixpanel framework target. When using IDFV, the ID will not change when you call `.reset()`, but will change upon app uninstalls/reinstalls.
</Note>

#### Custom Device ID Provider

<Note>
  The `deviceIdProvider` option requires Swift SDK [v5.2.0](https://github.com/mixpanel/mixpanel-swift/releases/tag/v5.2.0) or later.
</Note>

For advanced use cases, use the [`deviceIdProvider`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) closure to implement custom device ID generation logic. This allows you to control where device IDs are stored and whether they persist across `.reset()` calls.

If the provider returns `nil` or an empty string, the SDK will fall back to generating a default device ID (UUID or IDFV based on `useUniqueDistinctId`).

**Example Usage**

```swift Swift theme={"system"}
// create a device ID provider
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    deviceIdProvider: {
        return getYourCustomDeviceId()
    }
)

let mixpanel = Mixpanel.initialize(options: options)
```

**Persistent vs Ephemeral IDs**

Returning the same value each time the provider is called creates a persistent device ID that survives `.reset()` calls. Returning different values generates a new device ID on each reset.

```swift Swift theme={"system"}
// persistent ID - survives reset() calls
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    deviceIdProvider: {
        return getStoredDeviceId() // returns same value every time
    }
)

// ephemeral ID - changes on reset() calls
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    deviceIdProvider: {
        return generateNewDeviceId() // returns new value each time
    }
)
```

## Storing User Profiles

Once your users are identified, create [user profiles](/docs/data-structure/user-profiles) by setting profile properties to describe them. Example profile properties include "name", "email", "company", and any other demographic details about the user.

The Swift SDK provides a few methods for setting profile properties under the [`People`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html) class accessible via [`.people()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC6peopleAA6PeopleCSgvp). These methods will trigger requests to the [/engage API endpoint](/reference/profile-set).

### Setting Profile Properties

<Note>
  You must call `.identify()` before setting profile properties in order to associate the profile properties you set with the target user. If identify is not called, the profile update will be queued for ingestion until an identify call is made.
</Note>

You can set properties on a user profile with [`people.set(property:to:)`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html#/s:FC8Mixpanel6People3setFT8propertySS2toPs9AnyObject__T_).

If a profile property already exists, it will be overwritten with the latest value provided in the method. If a profile property does not exist, it will be added to the profile.

**Example Usage**

```swift Swift theme={"system"}
/// You must call identify to associate the profile update with the user
Mixpanel.mainInstance().identify(distinctId: "12345")

/// Set user's "Plan" profile prop to "Premium"
Mixpanel.mainInstance().people.set(properties: ["plan":"Premium", "$email":"joe.doe@example.com"])

/// Update "plan" to "Enterprise"
Mixpanel.mainInstance().people.set(properties: ["plan":"Enterprise"])
```

### Other Types of Profile Updates

There are a few other methods for setting profile properties. See a complete reference of the available methods [here](https://mixpanel.github.io/mixpanel-swift/Classes/People.html)

A few commonly used people methods are highlighted below:

<Tabs>
  <Tab title="setOnce()">
    The [`setOnce(properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html#/s:8Mixpanel6PeopleC7setOnce10propertiesySDySSAA0A4Type_pG_tF) method set profile properties only if they do not exist yet. If it is setting a profile property that already exists, it will be ignored.

    Use this method if you want to set profile properties without the risk of overwriting existing data.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// set profile properties for user "12345"
    Mixpanel.mainInstance().identify(distinctId: "12345")
    Mixpanel.mainInstance().people.set(properties: ["name":"Sam"])

    /// will be ignored since "name" already exists
    Mixpanel.mainInstance().people.setOnce(properties: ["name":"Samantha"])

    /// set "location" property since it does not exist
    Mixpanel.mainInstance().people.setOnce(properties: ["location":"us"])
    ```
  </Tab>

  <Tab title="append()">
    The [`append(properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html#/s:8Mixpanel6PeopleC6append10propertiesySDySSAA0A4Type_pG_tF) method appends values to a list profile property.

    Use this method to add additional values to an existing list property instead of redefining the entire list.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// set profile properties for user "12345"
    Mixpanel.mainInstance().identify(distinctId: "12345")
    Mixpanel.mainInstance().people.set(properties: [
        "roles":["sales","engineer"]
        ])


    /// add "legal" to "roles"
    /// new "roles" values are ['sales','engineer','legal']
    Mixpanel.mainInstance().people.append(properties: [
        "roles":"legal"
        ])

    /// append() allows duplicates
    // new "roles" values are ['sales','engineer','legal','legal']
    Mixpanel.mainInstance().people.append(properties: [
        "roles":"legal"
        ])
    ```
  </Tab>

  <Tab title="union()">
    The [`union(properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html#/s:8Mixpanel6PeopleC5union10propertiesySDySSAA0A4Type_pG_tF) method appends new values to a list property, excluding duplicates.

    Use this method to create a list profile property that only contains unique values without duplicates.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// set profile properties for user "12345"
    Mixpanel.mainInstance().identify(distinctId: "12345")
    Mixpanel.mainInstance().people.set(properties: [
        "roles":["sales","engineer"]
        ])

    /// will be ignored since "engineer" already exists in "roles"
    Mixpanel.mainInstance().people.union(properties: [
        "roles":"engineer"
        ])

    /// add "legal" to "roles"
    /// "roles" = ['sales','engineer','legal']
    Mixpanel.mainInstance().people.union(properties: [
        "roles":"legal"
        ])
    ```
  </Tab>

  <Tab title="increment()">
    The [`increment(property:by:)`](https://mixpanel.github.io/mixpanel-swift/Classes/People.html#/s:8Mixpanel6PeopleC9increment8property2byySS_SdtF) method increments a numeric property by a whole number.

    Use this method to add to or subtract from your numeric property based on its current value.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// set profile properties for user "12345"
    Mixpanel.mainInstance().identify(distinctId: "12345")
    Mixpanel.mainInstance().people.set(properties: ["age":25])

    /// increment "age" by 2
    Mixpanel.mainInstance().people.increment(property: "age", by: 2)

    /// use negative number to decrement
    /// decrement "age" by 5
    Mixpanel.mainInstance().people.increment(property: "age", by: -5)
    ```
  </Tab>
</Tabs>

## Group Analytics

<Note>
  Read more about [Group Analytics](/docs/data-structure/group-analytics) before proceeding. You will need to have the [group key defined in your project settings](/docs/data-structure/group-analytics#group-keys-in-project-settings) first.
</Note>

Mixpanel Group Analytics is a paid add-on that allows behavioral data analysis by selected groups, as opposed to individual users.

A group is identified by the `group_key` and `group_id`.

* `group_key` is the event property that connects event data to a group. (e.g. `company`)
* `group_id` is the identifier for a specific group. (e.g. `mixpanel`,`company_a`,`company_b`, etc.)

The Swift SDK provides a few methods for adding individual users to a group and setting group profile properties.

### Adding Users to a Group

[All events must have the group key as an event property in order to be attributed to a group](/docs/data-structure/group-analytics#group-keys-tracked-as-event-properties). Without the group key, an event cannot be attributed to a group.

Call the [`setGroup(groupKey:groupIDs:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC8setGroup8groupKey0E2IDySS_AA0A4Type_ptF) to register the current user to a group, which would add the `group_key` as an event property set to the `group_id` value to all events moving forward.

**Example Usage**

```swift Swift theme={"system"}
/// assign the current user to the "mixpanel" company group
Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

/// track "some_event"
/// event prop "company" = ["mixpanel"] is added automatically
Mixpanel.mainInstance().track(event: "some_event")


/// alternatively you can define the group key manually
Mixpanel.mainInstance().track(event: "some_event", properties: [
    "company": ["mixpanel"]])
```

**Multiple Groups**

[An event can be attributed to multiple groups](/docs/data-structure/group-analytics#attribute-events-to-multiple-groups) by passing in the `group_key` value as a list of multiple `group_id` values.

Call [`addGroup(groupKey:groupID:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC8addGroup8groupKey0E2IDySS_AA0A4Type_ptF) to add additional `group_id`s to an existing group key property.

**Example Usage**

```swift Swift theme={"system"}
/// assign the current user to the "mixpanel" company group
Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

/// add "mp-us" as an additional company group
Mixpanel.mainInstance().addGroup(groupKey: "company", groupID: "mp-us")

/// track "some_event"
/// event prop "company" = ["mixpanel","mp-us"] is added automatically
Mixpanel.mainInstance().track(event: "some_event")
```

### Adding Group Identifiers to User Profiles

To connect group information to a user profile, include the `group_key` and `group_id` as a user profile property using the `.people.set()` call.

**Example Usage**

```swift Swift theme={"system"}
/// You must call identify to associate the profile update with the user
Mixpanel.mainInstance().identify(distinctId: "12345")

/// set group key "company" as a user prop
/// with group id "mixpanel" as value
Mixpanel.mainInstance().people.set(properties: ["company":"mixpanel", "$email":"joe.doe@example.com"])
```

### Setting Group Profile Properties

Create a group profiles by setting group properties, similar to a user profile. For example, you may want to describe a company group with properties such as "ARR", "employee\_count", and "subscription".

To set group profile properties, specify the group that needs to be updated by calling [`getGroup(groupKey:groupID:)`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC8getGroup8groupKey0E2IDAA0D0CSS_AA0A4Type_ptF), then set the group properties by chaining the [`set(properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html#/s:8Mixpanel5GroupC3set10propertiesySDySSAA0A4Type_pG_tF) method, which will trigger a request to the [/groups API endpoint](/reference/group-set-property).

**Example Usage**

```swift Swift theme={"system"}
/// assign the current user to the "mixpanel" company group
Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

/// specify the target group using the group_key and group_id using getGroup()
/// set "industry" as a group profile prop to "analytics" using set()
Mixpanel.mainInstance().getGroup(groupKey: "Company", groupID: “mixpanel”).set(properties: [
    "industry": "analytics"
])
```

### Other Group Profile Methods

See all of the methods under the MixpanelGroup class [here](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html).

A few commonly used group methods are highlighted below:

<Tabs>
  <Tab title="setOnce()">
    The [`setOnce(properties:)`](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html#/s:8Mixpanel5GroupC7setOnce10propertiesySDySSAA0A4Type_pG_tF) method set group profile properties only if they do not exist yet. If it is setting a profile property that already exists, it will be ignored.

    Use this method if you want to set group profile properties without the risk of overwriting existing data.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// assign the current user to the "mixpanel" company group
    Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

    /// set group profile properties
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).set(properties: [
        "name": "Mixpanel"])

    /// ignored since "name" already exists
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).setOnce(properties: [
        "name": "mp"])

    /// set "country" group prop since it does not exist
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).setOnce(properties: [
        "country": "us"])
    ```
  </Tab>

  <Tab title="unset()">
    The [`unset(property:)`](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html#/s:8Mixpanel5GroupC5unset8propertyySS_tF) method removes a group property from a group profile.

    Use this method to delete unwanted group profile properties from a specific group profile.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// assign the current user to the "mixpanel" company group
    Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

    /// set group profile properties
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).set(properties: [
        "name": "Mixpanel",
        "employee_count": 100
    ])

    /// delete "employee_count" from the group profile
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).unset(properties: "employee_count")

    /// The group only has the "name" property remaining
    ```
  </Tab>

  <Tab title="union()">
    The [`union(key:values:)`](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html#/s:8Mixpanel5GroupC5union3key6valuesySS_SayAA0A4Type_pGtF) method append new values to a list property, excluding duplicates.

    Use this method to create a list profile property that only contains unique values without duplicates.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// assign the current user to the "mixpanel" company group
    Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

    /// set group profile properties
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).set(properties: [
        "name": "Mixpanel",
        "features": ["reports","alerts","cohorts"]
    ])

    /// add "data pipeline" to "features" prop
    /// ignore "alerts" since it is a duplicate value
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).union(key: "features",
        values: ["data pipeline","alerts"])
    ```
  </Tab>

  <Tab title="remove()">
    The [`remove(key:value:)`](https://mixpanel.github.io/mixpanel-swift/Classes/Group.html#/s:8Mixpanel5GroupC6remove3key5valueySS_AA0A4Type_ptF) method removes a value from a list-valued group profile property.

    Use this method to remove specific values from a list without affecting all of the other values in the list.

    **Example Usage**

    ```swift Swift theme={"system"}
    /// assign the current user to the "mixpanel" company group
    Mixpanel.mainInstance().setGroup(groupKey: "company", groupID: ["mixpanel"])

    /// set group profile properties
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).set(properties: [
        "name": "Mixpanel",
        "features": ["reports","alerts","cohorts"]
    ])

    /// remove "alerts" from "features"
    Mixpanel.mainInstance().getGroup(groupKey: "company", groupID: “mixpanel”).remove(
        key: "features", value: "alerts")

    /// "features" = ["reports","cohorts"]
    ```
  </Tab>
</Tabs>

## Session Replay

Install the [Session Replay SDK for Swift](/docs/tracking-methods/sdks/swift/swift-replay) to record replay data. Learn more about [Session Replay](/docs/session-replay) and [implementing Session Replay on iOS](/docs/tracking-methods/sdks/swift/swift-replay).

## Debugging and Logging

Enable debug mode by setting the [`loggingEnabled`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC14loggingEnabledSbvp) configuration to `true`.

**Example Usage**

```swift Swift theme={"system"}
/// enable debug log
Mixpanel.mainInstance().loggingEnabled = true
```

Learn more about [debugging](/docs/tracking-best-practices/debugging).

## Privacy-Friendly Tracking

You have control over the data you send to Mixpanel. The Swift SDK provides methods to help you protect user data.

Learn more about [Privacy](/docs/privacy/overview).

### Opt Out of Tracking

The Swift SDK is initialized with tracking enabled by default. Use the [`optOutTracking()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC14optOutTrackingyyF) method to opt the user out of data tracking and local storage for the current Mixpanel instance.

**Example Usage**

```swift Swift theme={"system"}
/// send "some_event"
Mixpanel.mainInstance().track(event: "some_event")

/// opt user out of tracking
/// SDK is prevented from sending any data
Mixpanel.mainInstance().optOutTracking()

/// this track call will not work
Mixpanel.mainInstance().track(event: "some_event")
```

#### Opt Out by Default

For GDPR compliance, you can initialize the SDK with users opted out of tracking by default using the [`optOutTrackingByDefault`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option (see [Configuration Reference](#configuration-reference)). Once the user consents to tracking, call [`optInTracking()`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelInstance.html#/s:8Mixpanel0A8InstanceC13optInTracking10distinctId10propertiesySSSg_SDySSAA0A4Type_pGSgtF) to start tracking.

**Example Usage**

```swift Swift theme={"system"}
/// create Mixpanel instance with users opted out of tracking by default
/// SDK is prevented from sending data
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    optOutTrackingByDefault: true
)
Mixpanel.initialize(options: options)

/// this track call will not work
Mixpanel.mainInstance().track(event: "some_event")

/// opt user into tracking
Mixpanel.mainInstance().optInTracking()

/// send "some_event"
Mixpanel.mainInstance().track(event: "some_event")
```

### Data Residency

<Note>
  Setting `serverURL` during initialization ensures all requests (events, profiles, and feature flags) use the correct endpoint from the start.
</Note>

#### EU Data Residency

Route data to Mixpanel's EU servers by setting the [`serverURL`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option to `https://api-eu.mixpanel.com` during initialization (see [Configuration Reference](#configuration-reference)).

**Example Usage**

```swift Swift theme={"system"}
/// Initialize Mixpanel with EU data residency
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    serverURL: "https://api-eu.mixpanel.com"
)
Mixpanel.initialize(options: options)
```

#### India Data Residency

Route data to Mixpanel's India servers by setting the [`serverURL`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option to `https://api-in.mixpanel.com` during initialization (see [Configuration Reference](#configuration-reference)).

**Example Usage**

```swift Swift theme={"system"}
/// Initialize Mixpanel with India data residency
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    serverURL: "https://api-in.mixpanel.com"
)
Mixpanel.initialize(options: options)
```

### Disable Geolocation

The Swift SDK parses the request IP address to generate geolocation properties for events and profiles. To disable geolocation and prevent IP-based tracking, set [`useIPAddressForGeoLocation`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) to `false` (see [Configuration Reference](#configuration-reference)).

You can configure this during initialization or change it after:

**Recommended: Configure During Initialization**

```swift Swift theme={"system"}
let options = MixpanelOptions(
    token: "YOUR_PROJECT_TOKEN",
    useIPAddressForGeoLocation: false
)
Mixpanel.initialize(options: options)
```

**Alternative: Update After Initialization**

```swift Swift theme={"system"}
/// Disable IP-based geolocation at runtime
Mixpanel.mainInstance().useIPAddressForGeoLocation = false
```

## Legacy Automatically Tracked Events

Mixpanel's SDKs have a legacy feature to automatically collect common mobile events. **We don't recommend enabling this**, as these events rely on client-side state and can be unreliable.

The [`trackAutomaticEvents`](https://mixpanel.github.io/mixpanel-swift/Classes/MixpanelOptions.html) option is set to `false` by default (see [Configuration Reference](#configuration-reference)). You only need to explicitly set this if you want to enable automatic event tracking.

See below table for automatic events tracked by the Swift SDK when `trackAutomaticEvents` is enabled:

| Raw Name          | Display Name          | Description                                                                                                                                                                                                                                                                                                                                           |
| ----------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \$ae\_first\_open | First App Open        | Tracks the first time the user has opened the app. This event is retriggered if the user reinstalls the app or clears local storage. A user property First App Open Date (`$ae_first_app_open_date`) is tracked to indicate the date when app was first opened.                                                                                       |
| \$ae\_updated     | App Updated           | Executes when a user updates the app from the previous version. A Version Updated (`$ae_updated_version`) property is tracked to store the new app version.                                                                                                                                                                                           |
| \$ae\_session     | App Session           | Executes when a user spends more than 10 seconds in the app. A Session Length (`$ae_session_length`) property is tracked to reflect the number of seconds user spent in the session. In addition, there are two user properties tracked: Total App Sessions (`$ae_total_app_sessions`) and Total App Session Length (`$ae_total_app_session_length`). |
| \$ae\_iap         | In App Purchase (IAP) | Executes when a user conducts an in-app purchase through your app. Mixpanel provides three properties for this event: Product Name (`$ae_iap_name`), Product Quantity (`$ae_iap_quantity`), and Product Price (`$ae_iap_price`).                                                                                                                      |

## Release History

[See All Releases](https://github.com/mixpanel/mixpanel-swift/releases).
