Analytics for iOS

Analytics for iOS makes it dead simple to send your data to any analytics or marketing tool without having to learn, test or implement a new API every time.

All of our libraries are open-source, so you can view Analytics for iOS on Github, or check out our browser and server-side libraries too.

Want to stay updated on releases? Subscirbe to the release feed.

Note: At the moment we can’t support tracking of watchkit extensions for the Apple watch. Email us if you’re interested in a watchkit SDK. For now we recommend tracking watch interactions via the iPhone app code.

Getting Started

Step 1: Install the SDK

The recommended way to install Analytics for iOS is via Cocoapods, since it means you can create a build with specific integrations, and because it makes it dead simple to install and upgrade.

First, add the Analytics dependency to your Podfile, like so:

pod 'Analytics', '~> 3.0'

Then in your application delegate’s - application:didFinishLaunchingWithOptions: method, setup the SDK like so:

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.trackApplicationLifecycleEvents = YES; // Enable this to record certain application events automatically!
configuration.recordScreenViews = YES; // Enable this to record screen views automatically!
[SEGAnalytics setupWithConfiguration:configuration];

Note: Automatically tracking lifecycle events (Application Opened, Application Installed, Application Updated) and screen views is optional via initialization config parameters, but highly recommended to hit the ground running with core events! See below for more info!

And of course, import the SDK in the files that you use it with:

#import <Analytics/SEGAnalytics.h>

Including Additional Client Side SDKs

In the interest of keeping our SDK lightweight, the Analytics pod only installs the Segment integration. This means that all your data will be sent via Segment’s servers to any tools you’ve enabled with server-side-compatible integrations.

You’ll likely want to bundle some additional integrations client side. Many advanced marketing automation and analytics tools will offer the option of including their SDK or electing to send data server to server depending on the features you need. Most optimization, deep linking, error tracking, and survey tools must be included on the device to leverage their core feature set.

In those cases, you’ll need to take some additional steps as shown in the source documentation here.

Now that the SDK is installed and setup, you’re ready to…


identify lets you tie a user to their actions and record traits about them. It includes a unique User ID and any optional traits you know about them.

We recommend calling identify a single time when the user’s account is first created, and only identifying again later when their traits are change.

Note: We automatically assign an anonymousId to users before you identify them. The userId is what connects anonymous activity across devices (e.g. iPhone and iPad).

Example identify call:

[[SEGAnalytics sharedAnalytics] identify:@"a user's id"
                                traits:@{ @"email": @"a user's email address" }];

This call is identifying a user by his unique User ID (the one you know him by in your database) and labeling him with name and email traits.

The identify call has the following fields:

userId NSString *, optionalThe database ID for this user. If you don’t know who the user is yet, you can omit the userId and just record traits. You can read more in the identify reference.
traits NSDictionary *, optionalA dictionary of traits you know about the user, like their email or name. You can read more about traits in the identify reference.
options NSDictionary *, optionalA dictionary of extra options for the call.

Analytics for iOS works on its own background thread, so it will never block the main thread for the UI or the calling thread.

Calling - identify: with a userId will write that ID to disk to be used in subsequent calls. That ID can be removed either by uninstalling the app or by calling reset.

Find details on the identify method payload in our Spec.


track lets you record the actions your users perform. Every action triggers what we call an “event”, which can also have associated properties.

To get started, our SDK can automatically tracks a few key common events with our Native Mobile Spec, such as the Application Installed, Application Updated and Application Opened. Simply enable this option during initialization.

You’ll also want to track events that are indicators of success for your mobile app, like Signed Up, Item Purchased or Article Bookmarked. We recommend tracking just a few important events. You can always add more later!

Example track call:

[[SEGAnalytics sharedAnalytics] track:@"Item Purchased"
                           properties:@{ @"item": @"Sword of Heracles", @"revenue": @2.95 }];

This example track call tells us that your user just triggered the Item Purchased event recording the item name of “Sword of Hercales” and revenue of 2.95.

track event properties can be anything you want to record. In this case, item and revenue.

The track call has the following fields:

event NSString *The name of the event. We recommend human-readable names like Song Played or Status Updated.
properties NSDictionary *, optionalA dictionary of properties for the event. If the event was Product Added to cart, it might have properties like price and productType.
options NSDictionary *, optionalA dictionary of extra options for the call.


The screen method lets you you record whenever a user sees a screen of your mobile app, along with optional extra information about the page being viewed.

You’ll want to record a screen event an event whenever the user opens a screen in your app. This could be a view, fragment, dialog or activity depending on your app.

Example screen call:

[[SEGAnalytics sharedAnalytics] screen:@"Photo Feed"
                            properties:@{ @"Feed Type": @"private" }];

The screen call has the following fields:

name NSString *The name of the screen, for example Signup or Home.
properties NSDictionary *, optionalA dictionary of properties for the screen. A screen Photo Feed might have properties like Feed Type or Sort Order.
options NSDictionary *, optionalA dictionary of extra options for the call.

Find details on the screen payload in our Spec.


group lets you associate an identified user user with a group. A group could be a company, organization, account, project or team! It also lets you record custom traits about the group, like industry or number of employees.

This is useful for tools like Intercom, Preact and Totango, as it ties the user to a group of other users.

Example group call:

[[SEGAnalytics sharedAnalytics] group:@"group123"
traits:@{ @"name": @"Initech", @"description": @"Accounting Software" }];

The group call has the following fields:

userId StringThe ID for this user in your database.
groupId StringThe ID for this group in your database.
traits Traits, optionalA dictionary of traits you know about the group. Things like: name or website.
options Options, optionalAn Options object lets you set a timestamp, enable or disable integrations, or send additional context.

Find more details about group including the group payload in our Spec.


alias is how you associate one identity with another. This is an advanced method, but it is required to manage user identities successfully in some of our integrations.

In Mixpanel it’s used to associate an anonymous user with an identified user once they sign up. For KISSmetrics, if your user switches IDs, you can use ‘alias’ to rename the ‘userId’.

Example alias call:

[[SEGAnalytics sharedAnalytics] alias:@"some new id"];

The alias call has the following fields:

newId NSString *The newId of the user you want to map to.
options NSDictionary *, optionalA dictionary of extra options for the call.

For more details about alias, including the alias call payload, check out our Spec.


The - reset method clears the SDK’s internal stores for the current user and group. This is useful for apps where users can log in and out with different identities over time.

Clearing all information about the user is as simple as calling:

[[SEGAnalytics sharedAnalytics] reset];

Migrating to v3

v3 is an API compatible release, but there are a few additional steps to bundle integrations.

In version 3, we’ve organized the integrations to be make the core SDK even leaner and smaller. The Analytics/Segmentio pod is not available any longer. It has been renamed to Analytics (which previously bundled all integrations). Version 3 of Analytics only includes the Segment integration. Which means, to bundle an integration, you must manually add that dependencies, like so:

pod 'Segment-Bugsnag'
pod 'Segment-Branch'
pod 'Segment-GoogleAnalytics'

…and then register them in your configuration when you initialize the SDK.

Note: If you are unsure about the name of the pod for a given SDK, you can always confirm on by searching for the integration in our app!

#import <Segment-GoogleAnalytics/SEGGoogleAnalyticsIntegrationFactory.h>
#import <Segment-Branch/BNCBranchIntegrationFactory.h>

SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];

// Add any of your bundled integrations.
[config use:[SEGGoogleAnalyticsIntegrationFactory instance]];
[config use:[BNCBranchIntegrationFactory instance]];

[SEGAnalytics setupWithConfiguration:config];

Submitting to the App Store

When you submit to the app store, be aware that Segment collects the IDFA for use in doing mobile install attribution with integrations like Mobile App Tracking. Even if you’re not currently doing mobile install attribution, if you get asked, “Does this app use the Advertising Identifier (IDFA)?” on this page, you’ll want to check the following three boxes:

  1. “Attribute this app installation to a previously served advertisement”
  2. “Attribute an action taken within this app to a previously served advertisement”
  3. “I, YOUR_NAME, confirm that this app, and any third party…”

Note, you should not check the box labeled “Serve advertisements within the app” unless you are actually going to display ads.

Selecting Integrations

The alias, group, identify, page and track calls can all be passed an object of integrations that lets you turn certain integrations on or off. By default all integrations are enabled.

You can enable or disable integrations by specifying an NSDictionary * in the options parameter of our methods as follows:

  @"integrations": @{

Here’s an example showing an - track: call that is sent to all enabled integrations except Mixpanel:

[[SEGAnalytics sharedAnalytics] track:@"Product Rated"
                              options:@{ @"integrations": @{ @"All": @YES, @"Mixpanel": @NO }}];

Integration flags are case sensitive and match the integration’s name in the docs (i.e. “AdLearn Open Platform”, “”, “MailChimp”, etc.).

Note: Available at the business level, filtering track calls can be done right from the Segment UI on your source schema page. We recommend using the UI if possible since it’s a much simpler way of managing your filters and can be updated with no code changes on your side.

Integrations in Debugger

If you are seeing any of your integrations turned off in the raw version of requests in the Segment live debugger, but you haven’t added those to your requests, like this:

"integrations": {
  "": false,
  "Google Analytics": false,
  "Localytics": false,
  "Mixpanel": false

These flags tell the Segment servers that a request was already made directly from the device through a bundled SDK. That way we don’t send a duplicate request via our servers to those services.


The SEGAnalyticsConfiguration class provides a set of properties that control various policies of the SEGAnalytics instance. You initialize it with a writeKey like so:

[SEGAnalytics setupWithConfiguration:[SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"]];
writeKey NSString *Your Segment source’s Write Key.

Location Services

You can set whether the analytics client should use location services. If YES and the host app hasn’t asked for permission to use location services, then the user may be presented with an alert view asking to do so. NO by default.

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.shouldUseLocationServices = YES;
[SEGAnalytics setupWithConfiguration:configuration];


You can set the number of events should queue before flushing. Setting this to 1 will send events as they come in (i.e. not send batched events) and will use more battery. 20 by default.

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.flushAt = 1;
[SEGAnalytics setupWithConfiguration:configuration];

You can also manually flush the queue:

[[SEGAnalytics sharedAnalytics] alias:@"glenncoco"];
[[SEGAnalytics sharedAnalytics] flush]

Application Lifecycle Tracking

Our SDK can automatically instrument common application lifecycle events such as “Application Installed”, “Application Updated” and “Application Opened”. Simply enable this option when you initialize the SDK.

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.trackApplicationLifecycleEvents = YES;
[SEGAnalytics setupWithConfiguration:configuration];

Automatic Screen Tracking

Our SDK can automatically instrument screen calls. It uses method swizzling to detect when ViewController’s are loaded and uses the label of the view controller (or the class name if a label is not available) as the screen name.

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.recordScreenViews = YES;
[SEGAnalytics setupWithConfiguration:configuration];

Bleeding Edge Releases

We publish stable releases every second Wednesday, when we tag and release the master branch.

After releasing, we also merge the dev branch merged into master. In general, code will be available on master for two weeks before being tagged as a stable release. During this two week period, it is available for use via Cocoapods and Carthage — our equivalent of bleeding edge releases. We recommend using this version to try out upcoming features and fixes that have not been published yet.

To use the master branch for CocoaPods users, use this line in your Podfile:

pod 'Analytics', :git => '', :branch => 'master'

To use the master branch for Carthage users, use this line in your Cartfile:

github "segmentio/analytics-ios" "master"


To see a trace of your data going through the SDK, you can enable debug logging with - debug::

[SEGAnalytics debug:YES];

Or disable it like this:

[SEGAnalytics debug:NO];

By default debug logging is disabled.

Proxy HTTP Calls

You can point the iOS SDK to your own hosted proxy of the Segment API. This will run the HTTP traffic for the Segment API through the proxy.

SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];

// Set a custom request factory which allows you to modify the way the library creates an HTTP request.
// In this case, we're transforming the URL to point to our own custom non-Segment host.
configuration.requestFactory = ^(NSURL *url) {
    NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
    // Replace YOUR_PROXY_HOST with the address of your proxy, e.g. = @"YOUR_PROXY_HOST";
    NSURL *transformedURL = components.URL;
    return [NSMutableURLRequest requestWithURL:transformedURL];

// Set any other custom configuration options.

// Initialize the SDK with the configuration.
[SEGAnalytics setupWithConfiguration:configuration];


Depending on the audience for your app (e.g. children) or the countries where you sell your app (e.g. the EU), you may need to offer the ability for users to opt-out of analytics data collection inside your app. You can turn off ALL integrations including Segment itself:

[[SEGAnalytics sharedAnalytics] disable];

Or if they opt-back-in, you can re-enable data collection:

[[SEGAnalytics sharedAnalytics] enable];

Bundling Integrations

By default, our Analytics pod bundles no integrations.

pod 'Analytics', '~> 3.1.0'

If you would like to bundle integrations, first add the dependencies you need. You can find these in our app when you open the integration for your source.

pod 'Segment-Bugsnag'
pod 'Segment-Branch'
pod 'Segment-GoogleAnalytics'

After adding the dependency, you must register the integration with our SDK.

#import <Segment-GoogleAnalytics/SEGGoogleAnalyticsIntegrationFactory.h>
#import <Segment-Branch/BNCBranchIntegrationFactory.h>

SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];

// Add any of your bundled integrations.
[config use:[SEGGoogleAnalyticsIntegrationFactory instance]];
[config use:[BNCBranchIntegrationFactory instance]];

[SEGAnalytics setupWithConfiguration:config];

We recommend bundling integrations on a need-to-use basis to reduce the size of your application. In some cases, the tools must be absolutely bundled, or the server side integration might be limited in comparison.

Anonymizing IP

We collect IP address for client-side (iOS, Android, Analytics.js and Xamarin) events automatically.

If you don’t want us to record your tracked users’ IP in integrations and S3, you can set your event’s context.ip field to . Our server won’t record the IP address of the client for libraries if the context.ip field is already set.


How big is the Segment SDK?

The core Segment SDK is extremely lightweight. It weighs in at about 212kb.

What if your SDK doesn’t support feature X?

For SDKs with unique functionality, or services with undocumented APIs, we bundle their SDKs into our SDK rather than proxying the data through our servers. The cool thing about this is that if you want to access a particularly unique feature from a tool’s native SDK, you can include the header file and call the method just as normal.

For example, you might want access to Flurry’s location logging or Localytics’s attribution parameters. To use the bundled SDK, just import the headers and then access the SDK as you would without Segment. We’ll still handle initialization, event, screen & user tracking, plus all the proxied services and data storage for you.

Here’s an example for Flurry location logging:

#import <Flurry-iOS-SDK/Flurry.h>

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
CLLocation *location = locationManager.location;
[Flurry setLatitude:location.coordinate.latitude

How Do I Use Push Notifications?

For services that send push notifications, you first want to create a Push SSL certificate following these steps. You then want to configure your application delegate to look like the code below, and replace your Segment source write key.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [SEGAnalytics setupWithConfiguration:[SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"]];

  if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotifications)]) {
    UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeSound |
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
  } else {
    UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound |
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
  return YES;

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [[SEGAnalytics sharedAnalytics] registeredForRemoteNotificationsWithDeviceToken:deviceToken];

// iOS 8+ only
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
  //register to receive notifications
  [application registerForRemoteNotifications];

How Do You Handle Unique Identifiers?

A key component of any analytics platform is consistently and accurately identifying users. Some kind of ID must be assigned and persisted on the device so that user actions can be effectively studied. This is especially important for funnel conversion analysis and retention analysis.

Naturally the Analytics SDK needs a unique ID for each user. To protect end-users’ privacy, Apple places restrictions on how these IDs can be generated and used. Here’s an explanation of these policies from Apple, and how we generate IDs in compliance.

Before iOS 5 developers had access to uniqueIdentifier which was a hardware-specific serial number that was consistent across different apps, vendors and installs. Starting with iOS 5, however, Apple deprecated access to this identifier. In iOS 6 Apple introduced the identifierForVendor which protects end-users from cross-app identification. In iOS 7 Apple restricted access to the device’s MAC address, which was being used by many developers as a workaround to get a device-specific serial number similar to like uniqueIdentifier.

Segment’s iOS library supports iOS 7+ by generating a UUID and storing it on disk. This is in line with the privacy policies required by Apple, maintains compatibility, and leaves open the option for multiple users on one device since the UUID can be regenerated.

Should I include each service’s SDK alongside Segment?

No, don’t include an SDK manually for a service we support. That will cause symbol conflicts/namespace collisions. Sometimes it can even fail silently :( So make sure you remove the old Google Analytics or Mixpanel SDK when you install Segment’s SDK.

How does the SDK queue API calls?

Our SDK queues API calls so that we don’t use up your user’s battery life by making a network request for each event tracked.

Here’s how queuing works for server-side integrations: When you make an API call (e.g. -track:) that call is added to the queue. The SDK sends the events to the server in batches (by default, the batch size is 100). The batches are then sent either when there are 20 or more events in the queue, on a scheduled timer every 30 seconds, or when the app goes to the background.

When the app is terminated we persist the queue to disk and load that data at app launch so there is no data loss. The queue behavior may differ in bundled integrations.

Can I set user traits without a User ID?

Yes! Just pass a nil value for the userId into your identify call, like this:

[[SEGAnalytics sharedAnalytics] identify: nil
    traits:@{ @"email": @"",
      @"Gender": @"F" }];

Do you support iOS 5?

Our SDK does not support iOS 5. If you need support for iOS 5 it’s possible by forking our iOS repo on GitHub and building the framework.

Is The Segment SDK Compatible with Swift?

Indeed! Swift’s compatibility with Objective-C lets you create a source that contains files written in either language, so to use our SDK from a Swift source just follow the instructions from Apple here.

Can I help develop an integration?

Yep! Our SDK is open-source. If you’d like to contribute, fix a bug, or add an integration - here’s documentation on how to do so. to add an integration, make sure you contact our partners team first.

How do I know when an integration is initialized?

The iOS library will post a notification to indicate when it initializes any integration so you can call it’s methods directly.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(integrationDidStart:) name:SEGAnalyticsIntegrationDidStart object:nil];

- (void)integrationDidStart:(NSNotification *)notification
    SEGAnalyticsIntegration *integration = notification.object;

    if ([ isEqualToString:@"Mixpanel"]) {
        // Call Mixpanel library methods here.


Some integrations, particularly mobile attribution tools (e.g. Kochava), require the IDFA (identifier for advertisers). The IDFA shows up in Segment calls in the debugger under context.device.advertiserId. In order for this value to be captured by the Segment SDK, ensure that you include the iAd framework.

Once you enable this, you will see the context.device.advertiserId populate and the context.device.adTrackingEnabled flag set to true.

Note: While the network is deprecated, the relevant framework is not.

Target has transitive dependencies that include static binaries

This is an issue that doesn’t have an out of the box solution due to Cocoapods limitations. The limitation occurs when an application is built in Swift, you are including use_frameworks! in your podfile, and are using a transitive dependency that is provided as a static library (such as Google Analytics, Flurry, AppsFlyer, etc.).

The best recommendation is to ask these tools to provide a dynamic framework instead of a static library.

If the tool does not provide a dynamic framework, the workaround is to copy the integration code manually into your project.

tvOS Support

As of Version 3.3.0 we now have support for tvOS through our Analytics-iOS sdk. You simply will follow the iOS quickstart documentation and you should be good to go!

If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!