Analytics for iOS


Analytics for iOS makes it 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 Segment’s libraries are open-source, so you can view Analytics for iOS on GitHub, or check out the Segment browser and server-side libraries too.

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

Note: Segment does not currently 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 using the iPhone app code.

Analytics-iOS and Unique Identifiers

One of the most important parts of any analytics platform is the ability to consistently and accurately identify users. To do this, the platform must assign and persist some form of identification on the device, so you can analyze user actions effectively. 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. This section explains Apple’s policies, and how Segment generates IDs in compliance with these policies.

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 many developers used as a workaround to get a similar device-specific serial number to replace uniqueIdentifier.

Segment’s iOS library supports iOS 7+ by generating a UUID and storing it on disk. This complies with Apple’s required privacy policies, maintains compatibility, and also enables correct tracking in situations where multiple people use the same device, since the UUID can be regenerated.

API call queueing in Analytics-iOS

The Segment SDK queues API calls rather than making a network request for each event tracked, to help improve the user’s battery life.

Packaged, or “device-mode” destinations (where Segment sends data directly from the user’s device using the destination’s integration SDK), might have their own queue behavior. Check the destination vendor’s documentation for details.

For cloud-mode destinations, when you make an API call (Track, Page, etc.) the Segment library adds that call to the queue, and sends the events to the Segment servers in batches. By default, the batch size is 100.

Batches are sent either:

  • when there are 20 or more events in the queue
  • on a scheduled timer, every 30 seconds
  • when the app goes to the background

To limit memory and disk usage, Segment only queues up to 1000 events. When the app is terminated, Segment saves the queue to disk, and loads that data again at app launch so there is no data loss.

Getting Started

About mobile connection modes

Segment defaults to using cloud-based connection mode (“cloud-mode”) for any destination connected to a mobile source, because this can help decrease the size of your final app package. When you use cloud-mode, Segment sends messages to the Segment servers, and then translates and forwards that data on to the downstream tools. This way, you only package the Segment mobile library with your app.

However, many destination tools that specifically deal with mobile interactions require that you use a device-based connection mode (“device-mode”) so that they can collect information directly on the mobile device. (You can check the full list of destinations and which connection modes they support.)

If you plan to use destinations that require device-mode, you must package the Segment-integration version of that tool’s SDK along with the Segment source library in your app. The Segment-integration SDK allows you to still collect the data with Segment, but also enables any device-based features, and still saves you space.

When you package a tool’s device-mode SDK with the Segment SDK, Segment sends the data directly to the tool’s API endpoint. Segment then also adds the tool to the integrations object and sets it to false, so that the data is not sent a second time from Segment servers.

For example, if you bundled the Segment SDK and Segment-Intercom library, you would see this in your payload:

"integrations": {
  "Intercom": false
  },

When you package Segment and the Segment-integration SDKs, you must use a dependency manager (such as Cocoapods or Gradle) to ensure that all SDKs are compatible and all of their dependencies are included. Segment does not support bundling mobile SDKs without a dependency manager.

Install the SDK

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

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

pod 'Analytics', '~> 4.1'

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

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.trackApplicationLifecycleEvents = true // Enable this to record certain application events automatically!
configuration.recordScreenViews = true // Enable this to record screen views automatically!
Analytics.setup(with: configuration)
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 using 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 Segment
#import <Segment/SEGAnalytics.h>

Including the SDKs for destinations using Device-mode

In the interest of keeping the Analytics-iOS SDK lightweight, the Analytics pod only installs the Segment destination. This means that all your data is sent through Segment’s servers to any tools you enable using the default Cloud-mode.

Some destinations require or offer Device-mode connections. For those destinations, you must take some additional steps as to package the device-mode SDKs.

Now that the Segment Analytics-iOS SDK is installed and set up, you’re ready to…

Configure and set up the SDK

The SEGAnalyticsConfiguration class provides a set of properties that control various policies of the SEGAnalytics instance. You initialize it with a writeKey as in the examples below:

Analytics.setup(with: AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY"))
[SEGAnalytics setupWithConfiguration:[SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"]];
writeKey NSString * Your Segment source’s Write Key.

Application Lifecycle Tracking

The Segment Analytics-iOS 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.

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.trackApplicationLifecycleEvents = true
Analytics.setup(with: configuration)
SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.trackApplicationLifecycleEvents = YES;
[SEGAnalytics setupWithConfiguration:configuration];

Automatic Screen Tracking

The Segment Analytics-iOS SDK can automatically instrument screen calls. It uses method swizzling to detect when ViewControllers are loaded, and uses the label of the view controller (or the class name if a label is not available) as the screen name. It removes the string “ViewController” from the name if one is present.

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.recordScreenViews = true
Analytics.setup(with: configuration)
SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.recordScreenViews = YES;
[SEGAnalytics setupWithConfiguration:configuration];

Automatic Push Notification Tracking

When you set trackPushNotifications to YES, the SDK automatically sends a Track event for Push Notification Received and Push Notification Tapped.

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.trackPushNotifications = true
Analytics.setup(with: configuration)
SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.trackPushNotifications = YES;
[SEGAnalytics setupWithConfiguration:configuration];

When you set trackDeepLinks to YES, the SDK automatically sends a Track event for Deep Link Opened.

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.trackDeepLinks = true
Analytics.setup(with: configuration)
SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.trackDeepLinks = YES;
[SEGAnalytics setupWithConfiguration:configuration];

Flushing

You can set the number of events that 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.

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")
configuration.flushAt = 1
Analytics.setup(with: configuration)
SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];
configuration.flushAt = 1;
[SEGAnalytics setupWithConfiguration:configuration];

You can also manually flush the queue:

Analytics.shared().alias("glenncoco")
Analytics.shared().flush()
[[SEGAnalytics sharedAnalytics] alias:@"glenncoco"];
[[SEGAnalytics sharedAnalytics] flush]

Data Collection

Now that the Segment SDK and any accompanying packaged SDKs are installed, you’re ready to collect some data!

Good to know: For any of the methods described in this doc, you can replace the properties and traits in the code samples with variables that represent the data collected.

Identify

Segment’s Identify method 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.

Segment recommends that you call Identify once when you first create the user’s account, and only call it again later when they update their traits or you change them.

Note: Segment automatically assigns an anonymousId to users before you identify them. The userId is what connects anonymous activities across devices (for example, iPhone and iPad).

Example identify call:

Analytics.shared().identify("a user's id", traits: ["email": "a user's email address"])
[[SEGAnalytics sharedAnalytics] identify:@"a user's id"
                                traits:@{ @"email": @"a user's email address" }];
userId NSString *, optional The 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 *, optional A 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 *, optional A 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 the Identify Spec documentation.

Track

Segment’s Track method 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, the Segment iOS SDK can automatically track a few key common events with the Segment Native Mobile Spec, such as the Application Installed, Application Updated and Application Opened. Enable this option during initialization.

You might also want to track events that are indicators of success for your mobile app, like Signed Up, Item Purchased or Article Bookmarked. Segment recommends tracking just a few important events to start out. You can always add more later! An example Track call might look like this:

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

This example Track call above tells you that your user just triggered the Item Purchased event, and records the item name of “Sword of Heracles” 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 *, optional A dictionary of properties for the event. If the event was Product Added to cart, it might have properties like price and productType.
options NSDictionary *, optional A dictionary of extra options for the call.

Screen

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:

Analytics.shared().screen("Photo Feed", properties: ["Feed Type": "private"])
[[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 *, optional A dictionary of properties for the screen. A screen Photo Feed might have properties like Feed Type or Sort Order.
options NSDictionary *, optional A dictionary of extra options for the call.

Find details on the Screen payload in the Screen Spec documentation.

Group

The Segment Group method 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.

An example Group call might look like this:

Analytics.shared().group("group123", traits: ["name": "Initech", "description": "Accounting Software"])
[[SEGAnalytics sharedAnalytics] group:@"group123"
traits:@{ @"name": @"Initech", @"description": @"Accounting Software" }];

The Group call has the following fields:

userId String The ID for this user in your database.
groupId String The ID for this group in your database.
traits Traits, optional A dictionary of traits you know about the group. Things like: name or website.
options Options, optional An Options object lets you set a timestamp, enable or disable destinations, or send additional context.

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

Alias

The Segment Alias method is how you associate one identity with another. This is an advanced method, but it is required to manage user identities successfully in some destinations.

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:

Analytics.shared().alias("some new id")
[[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 *, optional A dictionary of extra options for the call.

For more details about the Alias method, including the Alias call payload, check out the Alias Spec documentation.

AnonymousId

You can retrieve the anonymousId set by the library by using:

Analytics.shared().getAnonymousId
[[SEGAnalytics sharedAnalytics] getAnonymousId];

Reset

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:

Analytics.shared().reset()
[[SEGAnalytics sharedAnalytics] reset];

Events in the queue are not cleared, and are sent to Segment the next time the app starts. You might want to call Flush in combination before you call Reset.

Note: Each time you call reset, a new AnonymousId is generated the next time the app is opened, which can impact the number of Monthly Tracked Users (MTUs) you process.

Disabling Data Collection for Users who opt out

Depending on the audience for your app (for example, children) or the countries where you sell your app (for example, the EU), you might need to offer the ability for users to opt-out of analytics data collection from inside your app. You can turn off forwarding to ALL destinations including Segment itself using the following code:

[[SEGAnalytics sharedAnalytics] disable];
Analytics.shared().disable()

Or if the user opts back in, you can re-enable data collection:

Analytics.shared().enable()
[[SEGAnalytics sharedAnalytics] enable];

If you disable the Segment SDK in response to user opt-out, all Segment method invocations (Track, Screen, Identify, etc) are ignored. However, this does not disable any destination SDKs that you bundled along with Segment. You should consult the vendor documentation for those destinations, and invoke the corresponding disable methods for each packaged SDK to ensure that any automatic data collection stops.

Selecting Destinations

You can pass an integrations object on Page, Track, Alias, Group and Identify calls to turn specific destinations on or off. All destinations are enabled by default.

You can enable or disable destinations by specifying an NSDictionary * in the options parameter of the Segment methods as in the examples below:

options: [
  "integrations": [
    "ENABLED_INTEGRATION_NAME": true,
    "DISABLED_INTEGRATION_NAME": false
  ]
]
options:@{
  @"integrations": @{
    @"ENABLED_INTEGRATION_NAME": @YES,
    @"DISABLED_INTEGRATION_NAME: @NO
  }
}

The example below shows a Track call that is sent to all enabled destinations except Mixpanel:

Analytics.shared().track("Product Rated", properties: nil, options: ["integrations": ["All": true, "Mixpanel": false]])
[[SEGAnalytics sharedAnalytics] track:@"Product Rated"
                            properties:nil
                              options:@{ @"integrations": @{ @"All": @YES, @"Mixpanel": @NO }}];

Destination flags are case sensitive and match the destination’s name in the docs (for example “AdLearn Open Platform”, “awe.sm”, “MailChimp”, etc.).

Note: Business level customers can filter track calls from the Segment App from the source schema page. Segment recommends that you use this method when possible, because simpler, and can be updated without any code changes in your app.

Disabled destinations in the debugger

When you view raw payload data in the Segment Debugger, you might see an integrations object in the payload that indicates that some of your destinations are turned off, even if you didn’t specifically turn them off. You might see a payload that like the example below:

"integrations": {
  "Segment.io": false,
  "Google Analytics": false,
  "Localytics": false,
  "Mixpanel": false
}

When Segment sends data in Device-mode (directly from a user’s device) it sets the destination to false in the integrations object of the data that it sends to the Segment servers. This indicates that the data was sent directly from the user’s device to the destination endpoint, and prevents the Segment servers from sending the destination that same data again.

Logging

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

Analytics.debug(true)
[SEGAnalytics debug:YES];

Or disable it like this:

Analytics.debug(false)
[SEGAnalytics debug:NO];

By default debug logging is disabled.

Proxy HTTP(S) Calls

You can point the iOS SDK to your own hosted proxy of the Segment API.

This runs the HTTP traffic for the Segment API through the proxy.

let configuration = AnalyticsConfiguration(writeKey: "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 = { (url: URL) -> URLRequest in
    var result = URLRequest(url: url)
    if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
        components.host = "YOUR_PROXY_HOST"
        if let transformedURL = components.url {
            result = URLRequest(url: transformedURL)
        }
    }
    return result
}

// Set any other custom configuration options.
...

// Initialize the SDK with the configuration.
Analytics.setup(with: configuration)
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. aba64da6.ngrok.io.
    components.host = @"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];

Ad Tracking and IDFA

Starting iOS 14, applications must prompt users if that app needs to collect their Identifier for Advertisers (IDFA). Going forward with analytics-ios-4.1 and later, Segment doesn’t auto-collect IDFA. If your app or any integrations require the use of IDFA, you need to:

  1. import the AdSupport and App Tracking Transparency Frameworks by Apple
  2. pass the below code snippet to Segment config and start tracking events
  3. prompt the user for consent and collect the IDFA

You can use the following closure snippet to pass the value to analytics-ios as configurations:

import AdSupport

...

let configuration = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")

// Enable advertising collection
configuration.enableAdvertisingTracking = true
// Set the block to be called when the advertisingID is needed
// NOTE: In iOS 14, you'll need to manually do authorization elsewhere and only when it has been authorized, return the advertisingIdentifier to segment via the block below
configuration.adSupportBlock = { () -> String in
    return ASIdentifierManager.shared().advertisingIdentifier
}

Analytics.setup(with: configuration)
@import AdSupport;

...

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

// Enable advertising collection
configuration.enableAdvertisingTracking = YES;
// Set the block to be called when the advertisingID is needed
// NOTE: In iOS 14, you'll need to manually do authorization elsewhere and only when it has been authorized, return the advertisingIdentifier to segment via the block below
configuration.adSupportBlock = ^{
    return [[ASIdentifierManager sharedManager] advertisingIdentifier];
}

[SEGAnalytics setupWithConfiguration:configuration];

The same value for IDFA will used across all (device and cloud-mode) integrations.

Note: analytics-ios can continue to collect events without the IDFA until user is prompted and only upon user consent the advertisingId field is added to the event payload

Ad-tracking affects two keys under the context object of every event:

device.adTrackingEnabled true if SDK is setup with closure and user has consented, false otherwise
device.advertisingId idfa_value if user opts-in otherwise this key is skipped from event payload

If your use cases don’t require the need for IDFA collection you can skip this setup and under your event context you will see not see the device.adTrackingEnabled and device.advertisingId key/value in your event payload.

Bleeding Edge Releases

Segment publishes stable releases every second Wednesday by tagging and releasing the masterbranch.

After release, Segment also merges the release’s dev branch into master. In general, code is available on master for two weeks before it is tagged as a stable release. During this period, the code is available using Cocoapods and Carthage — our equivalent of bleeding edge releases. Segment recommends that you use this version to try out upcoming features and fixes that have not been published yet.

To use the master branch, use one of the following methods:

CocoaPods

Add this line in your Podfile:

pod 'Analytics', :git => 'https://github.com/segmentio/analytics-ios.git', :branch => 'master'

Packaging device-mode destination SDKs

By default, the Segment Analytics pod does not package any destination SDKs.

pod 'Analytics', '~> 4.1.0'

To add destinations using Device-mode, first add the dependencies you need. You can find these in the Segment app when you open the destination sheet for any mobile destination with a Device-mode option.

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

After you add the dependency, you must register the destination with the Segment SDK:

import Segment
import Segment-GoogleAnalytics
import Segment-Branch

AnalyticsConfiguration *config = AnalyticsConfiguration(writeKey: "YOUR_WRITE_KEY")

// Add any of your Device-mode destinations.
config.use(SEGGoogleAnalyticsIntegrationFactory.instance())
config.use(BNCBranchIntegrationFactory.instance())
...

Analyitcs.setup(with: config)
#import <Segment/SEGAnalytics.h>
#import <Segment-GoogleAnalytics/SEGGoogleAnalyticsIntegrationFactory.h>
#import <Segment-Branch/BNCBranchIntegrationFactory.h>

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

// Add any of your Device-mode destinations.
[config use:[SEGGoogleAnalyticsIntegrationFactory instance]];
[config use:[BNCBranchIntegrationFactory instance]];
...

[SEGAnalytics setupWithConfiguration:config];

Segment recommends that you use Device-mode destinations sparingly, to reduce the size of your application.

This page was last modified: 26 Oct 2020

Get started with Segment

Segment is the easiest way to integrate your websites & mobile apps data to over 300 analytics and growth tools.
or
Create free account