Skip to main content

Getting Started

Please refer to our Quickstart Guide. The Full API Reference, Library Source Code, and an Example Application are documented in our GitHub repo.

Installing the Library

You can install the Swift library by using CocoaPods, Carthage, or Swift Package Manager.
  1. In Xcode, select File > Add Packages…
  2. Enter the package URL for this repository and select version v2.8.0 or above.
After installing the library, import Mixpanel into AppDelegate.swift and initialize Mixpanel within application:didFinishLaunchingWithOptions: using your project token.
Swift

SDK Configuration Using MixpanelOptions

Data Residency: For projects with EU or India data residency, you must configure the SDK to use the correct regional endpoint. Events sent to the wrong region will not be ingested. Learn more about Privacy-Friendly Tracking
Configure the Mixpanel SDK using MixpanelOptions to customize tracking behavior, data residency, privacy settings, and more.

Configuration Reference

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.
After initialization, you can further customize the instance using methods on MixpanelInstance. Common Configuration Example
Swift
See detailed explanations of each option in the sections below.

Sending Events

Use .track(event:properties:) to send an event by providing the event name and any event properties. This will trigger a request to the /track API endpoint to ingest the event into your project.
The /track endpoint 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.
Example Usage
Swift

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:). 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

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() manually if you want to force a flush at a particular moment. Example Usage
Swift

Configuring Flush Interval

The default flush interval is 60 seconds. You can customize this using the flushInterval option in MixpanelOptions (see Configuration Reference). Set to 0 to disable automatic flushing entirely (requires manual .flush() calls). Recommended: Configure During Initialization
Swift
Alternative: Update After Initialization You can also update the flush interval dynamically using flushInterval.
Swift

Importing Historical Events

The Swift SDK is a tracking SDK designed for real-time tracking in a client-side environment. Calling .track(event:properties:) triggers a request to our /track API endpoint, 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 which is optimized for scripting and supports ingesting historical data. We recommend the Python SDK (see the .import_data() function) and mixpanel-utils module (see the 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 option in MixpanelOptions (see Configuration Reference). Example Usage
Swift

Setting Super Properties at Runtime

To register super properties at runtime, call .registerSuperProperties(_:). Use .registerSuperPropertiesOnce(_:) to register super properties without overwriting existing values. Example Usage
Swift
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
See more methods related to super properties in the complete library reference here.

Managing User Identity

You can handle the identity of a user using the .identify() and .reset() methods. Learn more about identity management and identifying users.

Identify

We recommend against calling .identify() for anonymous visitors to your site.
Call .identify() 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

Call Reset on Logout

Call .reset() 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. Example Usage
Swift
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 for details on using IDFV or implementing custom device ID logic.

Custom Device ID Generation

The Swift SDK provides two ways to customize device ID generation (see 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
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.

Using Device IDFV

Set useUniqueDistinctId 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
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.

Custom Device ID Provider

The deviceIdProvider option requires Swift SDK v5.2.0 or later.
For advanced use cases, use the deviceIdProvider 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
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

Storing User Profiles

Once your users are identified, create 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 class accessible via .people(). These methods will trigger requests to the /engage API endpoint.

Setting Profile Properties

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.
You can set properties on a user profile with people.set(property:to:). 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

Other Types of Profile Updates

There are a few other methods for setting profile properties. See a complete reference of the available methods here A few commonly used people methods are highlighted below:
The setOnce(properties:) 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

Group Analytics

Read more about Group Analytics before proceeding. You will need to have the group key defined in your project settings first.
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. Without the group key, an event cannot be attributed to a group. Call the setGroup(groupKey:groupIDs:) 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
Multiple Groups An event can be attributed to multiple groups by passing in the group_key value as a list of multiple group_id values. Call addGroup(groupKey:groupID:) to add additional group_ids to an existing group key property. Example Usage
Swift

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

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:), then set the group properties by chaining the set(properties:) method, which will trigger a request to the /groups API endpoint. Example Usage
Swift

Other Group Profile Methods

See all of the methods under the MixpanelGroup class here. A few commonly used group methods are highlighted below:
The setOnce(properties:) 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

Autocapture

The Mixpanel Swift SDK provides methods on the autocapture object to help you track common user interactions with minimal instrumentation. These methods fire standardized events that are recognized by the Mixpanel platform.

Screen View & Screen Leave

Modern iOS apps use a variety of UI frameworks — UIKit with view controllers, SwiftUI with NavigationStack, or a mix of both. Each defines and transitions between “screens” differently, making it impractical for the SDK to automatically detect screen boundaries across all setups. Instead, you hook trackScreenView and trackScreenLeave into your app’s navigation, giving you full control over what counts as a screen and when transitions happen. Track screen navigations using trackScreenView and trackScreenLeave. These methods fire the following events: Both events automatically include current_page_title (the screen name) and $mp_autocapture: true.
Call these methods from any view controller or SwiftUI view:

Passing Custom Properties

Both methods accept an optional properties parameter. For example, forwarding UTM params from a deep link:

Click Events

Beta. Autocaptured click events are in beta: the events and the properties they capture may change before general availability. They require Swift SDK v6.6.0 or later, and are disabled by default — you opt in with AutocaptureOptions at initialization.
Starting in v6.6.0, the SDK can capture taps for you, with no per-view instrumentation. Once enabled, it intercepts touches across every window in your app — including presented sheets and alerts — and works with both UIKit and SwiftUI. Three events are produced: All three carry $mp_autocapture: true, alongside the properties described in Tracked Properties.

Click

A $mp_click event is emitted for every tap that resolves to an element, whether or not that element handles the tap. Scrolls, swipes and long presses do not produce clicks. When the tap lands on a non-interactive child — such as a UILabel inside a UIButton — the SDK walks up to the nearest interactive ancestor (up to 10 levels) and reports that element’s identity. This keeps a button from being reported as its label. If no interactive ancestor is found, the tapped element’s own identity is used.

Dead Click

A $mp_dead_click event is emitted when a tap on an interactive element produces no visible response. The SDK snapshots the UI immediately after the tap, then compares it 500 ms later; if nothing has changed, the event is emitted. That time window is the default DeadClickOptions.timeWindowMs and is configurable. A dead click is always accompanied by the $mp_click for the same tap. Only interactive elements are candidates, so tapping a plain label or a decorative image never produces one. Controls with inherent visual feedback are excluded by type, because their response happens in a layer the detector cannot observe: UITextField, UITextView, UISwitch, UISlider, UIStepper, UISegmentedControl, UIDatePicker, UIPickerView and UIPageControl, plus the SwiftUI equivalents TextField, TextEditor, SecureField, Toggle, Slider, Stepper, Picker and DatePicker.
Detection is based on UI change only — the SDK does not observe network activity. A handler that fires a request but leaves the screen unchanged for the dead click time window is reported as a dead click, which is usually the user-perceived truth. Conversely, a response that only changes color, alpha or an animation may not register as a change.

Rage Click

A $mp_rage_click event is emitted when 4 or more taps land within 1000 ms of each other and within 44 pt on screen — the signature of a user hammering a control that isn’t responding. These three thresholds are the defaults — clickThreshold, timeWindowMs and radius on RageClickOptions — and are configurable. The event is emitted in addition to the individual $mp_click events, so four rapid taps produce four clicks and one rage click. Taps spread out in time or across the screen do not qualify. Rage clicks are a frustration signal: alongside dead clicks, they surface the places where your app is failing users without throwing an error. Break them down by $el_id to find the specific controls people are fighting with, or use them to segment sessions worth watching in Session Replay.

One-Time Setup: Element IDs

Do this once, before you enable click autocapture. It isn’t strictly required — autocapture works without it and every tap is still captured — but it’s what makes the data readable. An element with no identifier reports a positional hash like UIButton_a3f21c: it groups correctly, but it tells you nothing in a report and changes if you reorder siblings. So give every element you plan to measure a stable identifier first. In both frameworks the identifier belongs on the element that handles the tap — the SDK walks up to the nearest interactive ancestor and reads identity from there, so an identifier on a non-interactive wrapper is never used.
  • UIKit: For storyboard and XIB views, set the identifier in the Identity inspector → Accessibility → Identifier field instead of in code.
  • SwiftUI: Reading the identifier back requires iOS 18 or later — see the warning under Element ID Resolution. On iOS 15–17 these elements fall back to the hash whatever you set, so plan your reports accordingly.
  • accessibilityIdentifier is not accessibilityLabel: The identifier is developer-facing and never announced by VoiceOver, which is what makes it safe to use as an ID; the label is accessibility metadata and is never used as an identifier. Setting only a label leaves the element on the hash fallback.
Full precedence rules are in Element ID Resolution.

Enabling Click Autocapture

Pass an AutocaptureOptions instance through MixpanelOptions at initialization. Passing none leaves autocapture entirely uninitialized.
Swift
Each signal is configurable, and can be turned off independently:
Swift
Autocapture is iOS-only — not available on Mac Catalyst, tvOS, watchOS or visionOS — and does not run inside app extensions.

Disabling Click Autocapture

Autocapture is a decision made at initialization: omit autocaptureOptions and none of the machinery is constructed. To turn it off in an app that already ships with it enabled, either stop passing the options, or disable each signal:
Swift
There is no runtime toggle. Autocapture starts or doesn’t at initialization, and it respects opt-out: it does not start when tracking is opted out, and stops and restarts with optOutTracking() and optInTracking().

Tracked Properties

Every click, dead click and rage click event carries:
Autocapture does not capture element text: there is no $el_text property. There is also no $attr-aria-label property. accessibilityLabel is accessibility metadata — surfaced to assistive technologies such as VoiceOver rather than shown on screen — and it can carry personal data, so the SDK neither reports it nor uses it as an identifier.

Element ID Resolution

$el_id is resolved by the SDK using fixed rules — it is not configurable. Understanding the order is the key to getting readable IDs in your reports. UIKit:
  1. accessibilityIdentifier — framework-internal values such as _private or AXID-1 are skipped
  2. <ClassName>_<hash> — the anonymous fallback
SwiftUI:
  1. .accessibilityIdentifier("...") — read from SwiftUI’s accessibility element tree
  2. <ClassName>_<hash> — the anonymous fallback
SwiftUI identifiers need iOS 18+. SwiftUI never sets accessibilityIdentifier on the backing UIKit view — it lives in the accessibility element tree, which the SDK reads with accessibilityHitTest. That query is available on iOS 18 and later, and returns nothing when the tree has not been materialized. On iOS 15–17, SwiftUI elements fall back to <ClassName>_<hash> regardless of the identifier you set. UIKit views are unaffected.
About the hash fallback: the hash is derived from the element’s position in the hierarchy, not its instance, so it is identical across app launches. That makes it groupable, but it describes a position rather than a thing: reordering siblings changes it, and two rows of the same list differ by index rather than by content.
Review your identifiers for personal data. $el_id is derived from identifiers you set in your own code, so its contents are under your control — and Mixpanel receives them as-is. An identifier built from user data (user_4172@example.com_row, an account number, an order ID) sends that data to Mixpanel as an event property. Before you rely on click autocapture in production, tap through your key flows with SDK logging enabled, review the $el_id values the SDK reports, and confirm none of them carry personally identifiable information.

Best Practices

  • Give every element you want to measure a stable accessibilityIdentifier. button.accessibilityIdentifier = "checkout_button" in UIKit, .accessibilityIdentifier("checkout_button") in SwiftUI. Without one, the element reports a positional hash — groupable, but unreadable in reports, and it changes if you reorder siblings.
  • Put the identifier on the element that handles the tap, not on a wrapper around it. The walk-up finds the nearest interactive ancestor and reads identity from there, so an identifier on a non-interactive container is never used.
  • Keep identifiers static across renders. One built from a row index, a timestamp or a product name produces a new $el_id per render, which scatters one control across many rows in your reports.
  • On SwiftUI below iOS 18, expect hashes. If those versions matter to your reports, host the control in an identifiable UIKit view, or track those flows manually with trackClick.
  • Verify — and review for PII — before you rely on the data. Set loggingEnabled = true, tap through your key flows, and confirm the reported $el_id values are the ones you expect and that none of them contain personal data. Identifiers are yours to choose, so keeping PII out of them is yours to confirm.

Session Replay

Install the Session Replay SDK for Swift to record replay data. Learn more about Session Replay and implementing Session Replay on iOS.

Debugging and Logging

Enable SDK logs

Enable debug mode by setting the loggingEnabled configuration to true. Example Usage
Swift
Learn more about debugging.

Network Failover

Configure a backup host for automatic failover when the primary API endpoint is unreachable. The default primary endpoint is api.mixpanel.com (or your configured custom endpoint for EU/India data residency or proxy server). This can be used as a troubleshooting fallback when network calls to the Mixpanel endpoint are blocked or unreachable. Setup
Swift
The SDK automatically retries failed requests to the backup host, preserving the same URL path, authentication, and headers as the primary. How It Works Failover triggers:
  • Network failures (connection timeout, DNS errors)
  • Non 4xx HTTP status codes
No failover for:
  • Client errors (HTTP 4xx) - indicates invalid request
  • Successful responses (HTTP 200 OK)
  • Parse errors
This works with proxy server setups as well - if the proxy fails, the backup will be tried. Requirements Your backup host must:
  • Support the same API endpoints (/track/, /engage/, /groups/)
  • Accept the same authentication mechanism as the primary host
  • Use the same URL scheme and port as configured for the primary host

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.

Opt Out of Tracking

The Swift SDK is initialized with tracking enabled by default. Use the optOutTracking() method to opt the user out of data tracking and local storage for the current Mixpanel instance. Example Usage
Swift

Opt Out by Default

For GDPR compliance, you can initialize the SDK with users opted out of tracking by default using the optOutTrackingByDefault option (see Configuration Reference). Once the user consents to tracking, call optInTracking() to start tracking. Example Usage
Swift

Data Residency

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

EU Data Residency

Route data to Mixpanel’s EU servers by setting the serverURL option to https://api-eu.mixpanel.com during initialization (see Configuration Reference). Example Usage
Swift

India Data Residency

Route data to Mixpanel’s India servers by setting the serverURL option to https://api-in.mixpanel.com during initialization (see Configuration Reference). Example Usage
Swift

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 to false (see Configuration Reference). You can configure this during initialization or change it after: Recommended: Configure During Initialization
Swift
Alternative: Update After Initialization
Swift

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 option is set to false by default (see 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:

Release History

See All Releases.