iOS SDK v2 Beta

Use the RudderStack iOS SDK v2 to send events from your iOS/macOS/tvOS/watchOS apps to various destinations.

The RudderStack iOS SDK lets you track the customer event data from your iOS, macOS, tvOS, and watchOS applications and send it to the specified destinations via RudderStack.

success
  • tvOS is supported in version 1.1.0 and above
  • watchOS is supported in version v1.3.1 and above
  • macOS is supported in version 2.0.0 and above

Refer to the GitHub codebase to get a more hands-on understanding of the SDK.


SDK setup requirements

To set up the RudderStack iOS SDK, the following prerequisites must be met:

iOS source write key
  • You also need a data plane URL. Refer to the Glossary for more information on the data plane URL and where to find it.
success
The Setup tab in the RudderStack dashboard (seen above) has an SDK installation snippet containing both the write key and the data plane URL. You can use it to integrate the iOS SDK into your project.
  • Finally, you need a Mac with the latest version of Xcode.

Installing the RudderStack iOS SDK

The RudderStack iOS SDK is distributed through Cocoapods and Carthage.

success
The recommended and easiest way to add the SDK to your project is through Podfile.

Follow these steps to install the SDK depending on your preferred method:

Remember to include the following code in all the .m and .h files (Objective-C) or the .swift files where you want to refer to or use the RudderStack SDK classes:

RudderStack uses SQLite to temporarily store the events before sending them to the data plane. Making calls which are not thread-safe, like SQLite.shutdown(), might lead to unexpected crashes.

Swift Package Manager

You can also install the iOS SDK through Swift Package Manager (SPM) via one of the following methods:

Initializing the RudderStack client

To initialize the RudderStack client, place the following code in your AppDelegate file under the didFinishLaunchingWithOptions method:

RudderStack automatically tracks the following application lifecycle events:

You can disable these events using the trackLifecycleEvents method of RSConfig by passing false. However, it is highly recommended to keep them enabled.

Configuring the RudderStack client

You can configure your client based on the following parameters using RSConfig:

ParameterTypeDescriptionDefault value
logLevelRSLogLevelControls how much of the log you want to see from the SDK.RSLogLevel.none
dataPlaneUrlStringYour data plane URL.https://hosted.rudderlabs.com
flushQueueSizeIntegerNumber of events in a batch request sent to the server.30
dbCountThresholdIntegerNumber of events to be saved in the SQLite database. Once the limit is reached, older events are deleted from the database.10000
sleepTimeoutIntegerMinimum waiting time to flush the events to the server.10 seconds
trackLifecycleEventsBooleanDetermines if the SDK will capture application life cycle events automatically.true
autoSessionTrackingBooleanDetermines if the SDK automatically tracks user sessions. See Tracking user sessions for more information.true
sessionTimeoutIntegerMaximum inactivity period before the session expires.300000 ms (5 minutes)
recordScreenViewsBooleanDetermines if the SDK will capture will capture screen view events automatically.false
controlPlaneUrlStringThis parameter should be changed only if you are self-hosting the control plane. Refer to the Self-hosted control plane section below for more information. The SDK will add /sourceConfig along with this URL to fetch the required configuration.https://api.rudderlabs.com

Self-hosted control plane

If you are using a device mode destination like Adjust, Firebase, etc., the SDK needs to fetch the required configuration from the control plane. If you are using the Control Plane Lite utility to host your own control plane, then follow the steps in this section and specify controlPlaneUrl in RSConfig that points to your hosted source configuration file.

warning
Do not pass the controlPlaneUrl parameter during the SDK initialization if you are using RudderStack Cloud. This parameter is supported only if you are self-hosting the control plane using the Control Plane Lite utility.

The iOS SDK integrates with the OneTrust consent manager and lets you specify the user’s consent during initialization. For more information, refer to the OneTrust Consent Management for iOS guide.

Tracking user sessions

info
The iOS SDK v2 supports session tracking starting v2.3.0.

By default, the iOS SDK automatically tracks user sessions. RudderStack automatically determines the start and end of a user session depending on the inactivity time configured in the SDK (default time is 5 minutes).

warning
To automatically track sessions using the iOS SDK, the trackLifecycleEvents should be set to true while initializing the SDK. This is because RudderStack considers the Application Opened, Application Installed, or Application Updated events as the start of a new session.

To disable automatic session tracking, set autoSessionTracking to false.

For more information on user sessions and tracking them using the iOS SDK, see Session Tracking.

Supported API calls

The iOS SDK supports all the API calls specified in the RudderStack Events Spec guide. These include identify, track, screen, group, alias, and reset calls.

Identify

The call lets you identify a visiting user and associate them to their actions. It also lets you record the traits about them like their name, email address, etc. Once you identify the user, the SDK persists all the user information and passes it on to the subsequent track or screen calls. To reset the user identification, you can use the reset method.

info
RudderStack captures deviceId and uses that as anonymousId for identifying unknown users. This helps in tracking the users across the application installation.
info
According to the Apple documentation, if a device has multiple apps from the same vendor, all the apps will be assigned the same deviceId. If all the applications from the vendor are uninstalled, then a new deviceId will be assigned to the apps on the next install.

An sample identify call is shown below:

The identify method accepts the following parameters:

NameData typePresenceDescription
userIdNSStringRequiredUniquely identifies the visiting user.
traitsNSDictionaryOptionalInformation on the user traits. Use the dict method of RudderTraits to convert to NSDictionary easily.
optionRSOptionOptionalExtra options for the identify event.

Setting your own anonymous ID

By default, RudderStack uses the deviceId as anonymousId. To set your own anonymousId, you can use the setAnonymousId method as shown:

Track

The call lets you record the user events along with any properties associated with them.

A sample track event is shown below:

track method accepts the following parameters:

NameData typePresenceDescription
eventNameNSStringRequiredName of the tracked event.
propertiesNSDictionaryOptionalExtra data properties to be sent along with the event.
optionRSOptionOptionalExtra event options.

Screen

The screen call lets you record whenever a user views their mobile screen, with any additional relevant information about the screen.

A sample screen event is as shown:

The screen method accepts the following parameters:

NameData typePresenceDescription
screenNameNSStringRequiredName of the screen viewed by the user.
propertiesNSDictionaryOptionalExtra property object to be passed along with the screen call.
optionRSOptionOptionalExtra options to be passed along with the screen call.

Group

The call lets you link an identified user with a group like a company, organization, or an account. It also lets you record any traits associated with that group, like the name of the company, number of employees, etc.

A sample group call is shown below:

The group method accepts the following parameters:

NameData typePresenceDescription
groupIdStringRequiredThe unique identifier of the group with which you want to associate your user.
traitsNSDictionaryOptionalAny other property of the organization you want to pass along with the call.
optionRSOptionOptionalExtra event-level options to be passed along with the group call.
warning
The iOS SDK does not persist the group traits across the sessions.

Alias

The alias call associates the user with a new identification. A sample alias call is shown below:

Alternatively, you can use the following method signature:

NameData typePresenceDescription
newIdStringRequiredThe new userId you want to assign to the user.
optionRSOptionOptionalEvent-level options.
info
RudderStack replaces the old userId with the newUserId and persists that identification across the sessions.

Reset

You can use the reset method to clear the persisted user traits from the identify call. This is required for the user logout operation.

In session tracking, calling the reset method clears the current sessionId and generates a new one.

Setting a custom ID

You can pass a custom ID along with the standard userId in all your API calls. RudderStack adds this value under context.externalId.

The SDK does not not persist the externalId information across other API calls. To use it, you will need to pass externalId in every event.

The following snippet shows how to add an externalId to your identify event:

Enabling/disabling user tracking via the setOptOutStatus API (GDPR support)

RudderStack gives the users (for example, an EU user) the ability to opt out of tracking any user activity until they give their consent. You can do this by leveraging RudderStack’s setOptOutStatus API.

The setOptOutStatus API takes YES/NO (Objective-C) or true/false (Swift) as a Boolean value to enable or disable the user tracking activities. This flag persists across device reboots.

info
You need to call the setoptOutStatus API with the relevant parameter only once, as the information persists within the device even if you reboot it.

The following snippet highlights the use of the setoptOutStatus API to disable user tracking:

Once the user grants their consent, you can enable user tracking once again using the setOptOutStatus API by passing NO or false:

Supporting push notifications for device mode destinations

With the iOS SDK, you need not call the individual destination’s API in your app to implement the push notifications support; calling the SDK’s push notification API is sufficient.

warning
This feature is specific to RudderStack iOS SDK v2 and is not available in the earlier SDK versions. Also, it is only applicable for the device mode integrations.

To enable push notifications for your device mode destinations, the SDK provides the following functions:

To implement these functions, go to your AppDelegate file and add the following lines:

Setting the device token for push notifications

To pass push notifications to the destinations that support it, you can pass your device token using the setDeviceToken method:

RudderStack sets the device token under context.device.token.

Setting the advertisement ID

RudderStack separates the IDFA collection from the core library so that you have better control over it.

You can pass the IDFA to the setAdvertisementId method to set it under context.device.advertisingId:

You can pass ATTrackingManager.trackingAuthorizationStatus to RudderStack and it is passed along to the relevant destinations as configured.

For example, AppsFlyer accepts this parameter for the attribution to work in their server-to-server events flow.

You can pass the following options to the setAppTrackingConsent method to set the relevant authorization consent:

  • RSATTNotDetermined
  • RSATTRestricted
  • RSATTDenied
  • RSATTAuthorize

Filtering device mode events

When sending events to a destination via device mode, you can explicitly specify which events should be discarded or allowed to flow through - by allowlisting or denylisting them.

info
Refer to the Client-side Event Filtering guide for more information on this feature.

Enabling/disabling events for specific destinations

The RudderStack iOS SDK lets you enable or disable event flow to a specific destination or all the destinations to which the source is connected. You can specify these destinations by creating a RSOption object as shown:

The keyword All in the above snippet represents all the destinations the source is connected to. The SDK sets its value to true by default.

info
Make sure the DESTINATION_DISPLAY_NAME you specify above should exactly match the destination name as shown in the RudderStack dashboard.

You can pass the destinations specified to the SDK in the following two ways:

Method 1: Passing destinations while initializing the SDK

This approach is helpful when you want to enable/disable sending the events to the destinations across all the event calls made using the SDK.

Method 1: Passing destinations while initializing the SDK

This approach is helpful when you want to enable/disable sending only specific events to the destinations.

If you use the RSOption object to specify the destinations both while initializing the SDK as well as making an event call, then RudderStack will consider only the destinations specified at the event level.

Debugging

If you run into any issues regarding the RudderStack iOS SDK, you can enable VERBOSE or DEBUG logging to determine the issue.

To enable the logging, change your RSClient initialization as shown:

Adding Chromecast support

Google Chromecast is a device that plugs into your TV or monitor with an HDMI port, and can be used to stream content from your phone or computer.

RudderStack supports integrating the iOS SDK with your Cast app. Follow these instructions to build your iOS sender app. Then, add the iOS SDK to it. Follow the Google Cast developer guide for more details.

Developing a device mode destination

This section details the steps required to develop a device mode destination in case RudderStack doesn’t support it already.

More information on the RudderStack device mode can be found in the Connection Modes guide.

  1. Create a RSCustomDestination.swift file by extending RSDestinationPlugin:
class RSCustomDestination: RSDestinationPlugin {
    var key: String = "Custom"
    var controller = RSController()
    var type: PluginType = .destination
    var RSClient.sharedInstance(): RSClient?
    
    func update(serverConfig: RSServerConfig, type: UpdateType) {
        guard type == .initial else { return }
        // Some code
    }
    
    func track(message: TrackMessage) -> TrackMessage? {
        // Some code
        return message
    }
    
    func identify(message: IdentifyMessage) -> IdentifyMessage? {
        // Some code
        return message
    }
    
    func screen(message: ScreenMessage) -> ScreenMessage? {
        // Some code
        return message
    }
    
    func group(message: GroupMessage) -> GroupMessage? {
        // Some code
        return message
    }
    
    func alias(message: AliasMessage) -> AliasMessage? {
        // Some code
        return message
    }
    
    func flush() {
        // Some code
    }
    
    func reset() {
        // Some code
    }
}
  1. Then, create a CustomDestination class file by extending RudderDestination and initialize RSCustomDestination inside init():
@objc
class CustomDestination: RudderDestination {
    override init() {
        super.init()
        plugin = RSCustomDestination()
    }
}
  1. For Objective-C projects, a dialog box will appear while creating the Swift file - asking you to create a bridging header if it does not exist already. In this case, choose Create Bridging Header. This creates a <PROJECT_MODULE_NAME>-Bridging-Header.h file.

  2. After creating the Bridging Header, search Objective-C Generated Interface Header Name in Build Settings and keep the header name handy. This should be something like <PROJECT_MODULE_NAME>-Swift.h.

  3. Finally, add the CustomDestination with the RudderStack iOS SDK after its initialization:

Privacy manifest

Your apps and third-party SDKs (usually distributed as Swift packages, XCFrameworks, or framework bundles) contain a privacy manifest file named PrivacyInfo.xcprivacy. It records the data collected by your app/third-party SDK and the associated required reason API.

You need to record the reasons in your privacy manifest for each data type your app/SDK collects along with the category of required reasons API that it uses.

See the Apple developer documentation for more information on creating a privacy manifest.

info

Starting Spring 2024, you are required to include an approved reason in your app’s privacy manifest that accurately reflects how your app uses the API.

This is a mandatory requirement to upload a new app/app update to the App Store Connect. For more information, see this Apple update.

Privacy Accessed API Types

NSPrivacyAccessedAPITypes is an array of dictionaries describing the API types your app/third-party SDK accesses that have been designated as APIs that require reasons to access.

The RudderStack iOS SDK only uses the userDefaults API to store user and context information and it is declared in the privacy manifest in the iOS SDK repository.

Privacy tracking domains

NSPrivacyTrackingDomains is an array of strings listing the internet domains that your app/third-party SDK connects to for tracking purposes. If the user has not granted the tracking permissions through the App Tracking Transparency framework, the network requests to these domains fail and you get an error on your app.

If your application utilizes data for tracking users as outlined by Apple, it is important to seek the user’s consent first. Also, make sure to include the following domain in your app’s privacy manifest under the purpose NSPrivacyTrackingDomains:

  • rudderstack.com/

Privacy Nutrition Label Types

NSPrivacyCollectedDataTypes is an array of dictionaries that describe the data types your app/third-party SDK collects.

The RudderStack iOS SDK includes an array of Privacy Nutrition Label Types for the following automatically-collected fields:

DataLinked to userUsed for trackingCollection purpose
App versionNoNo
  • Developer advertising or marketing
  • Analytics
App nameNoNo
  • Developer advertising or marketing
  • Analytics
Device IDNoNo
  • Developer advertising or marketing
  • Analytics
  • Third-party advertising

See the Apple developer documentation for more information on the above collection purposes.

FAQ

I’m facing issues building with Carthage on XCode 12. What should I do?

If you’re facing an issue with Carthage and XCode 12, you can follow this workaround suggested by the Carthage team.

Does the iOS SDK support the tvOS, macOS, and watchOS platforms?

Yes, the iOS SDK supports tvOS and watchOS platforms. Refer to the table below for the version details:

PlatformSupported SDK version
tvOS1.1.0 and above
watchOS1.3.0 and above
macOS2.0.0 and above

How do I migrate from an older SDK version (v1.x) to the current version?

To migrate from the older SDK versions, update the usage of the following classes:

Previous NameUpdated Name
RudderClientRSClient
RudderConfigRSConfig
RudderLogLevelDebugRSLogLevelDebug

How can I get the user traits after making the identify call?

You can get the user traits after making an identify call in the following way:

How does the SDK handle different client/server errors?

In case of client-side errors, for example, if the source write key passed to the SDK is incorrect, RudderStack gives a 400 Bad Request response and aborts the operation immediately. For other types of network errors, for example, invalid data plane URL, the SDK tries to flush the events to RudderStack in an incremental manner (every 1 second, 2 seconds, 3 seconds, and so on).

Why is there a difference between timestamp and received_at for iOS events vs. Android events sent at the same time?

This scenario is most likely caused by the default behavior of iOS apps staying open in the background for a short period of time after a user closes them.

When a user closes an iOS or Android app, the events will still continue to be sent from the queue until the app closes in the background. Any events still in the queue will be retained until the user reopens the app. Due to this lag, there are some scenarios where there can be significant differences between timestamp (when the event was created) and received_at (when RudderStack actually receives the event).

For Android apps, events can be sent from the background after apps close for a longer period of time than iOS apps, therefore, more of the events coming from the Android SDK have closer timestamp and received_at times.

Does RudderStack integrate with SKAdNetwork?

RudderStack does not integrate with SKAdNetwork. However, SKAdNetwork can be directly integrated into an iOS application alongside RudderStack.

Yes, you can. Refer to the Enabling/disabling user tracking via the setOptOutStatus API section for more information.

How does the iOS SDK handle events larger than 32KB?

The iOS SDK drops any events greater than 32KB.

Why am I getting a warning in Points of Interest instruments?

You may get a warning in your Points of Interest instrument if rudderstack.com/ is not listed in your app’s NSPrivacyTrackingDomain key in any privacy manifest. It may be following users across multiple apps and websites to create user profiles for apps that contact this domain.

To resolve this issue, make sure to:

  • Seek user consent, especially if your app utilizes data for tracking users as outlined by Apple.
  • Include the rudderstack.com/ domain in your app’s privacy manifest under the purpose NSPrivacyTrackingDomains. See Privacy tracking domains for more information.


Questions? Contact us by email or on Slack