Use the RudderStack iOS SDK v2 to send events from your iOS/macOS/tvOS/watchOS apps to various destinations.
20 minute read
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.
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.
You will also need the data plane URL associated with your RudderStack workspace.
In the dashboard, the Setup tab for the source 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.
Installing the RudderStack iOS SDK
The RudderStack iOS SDK is distributed through Cocoapods and Carthage.
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:
Add the SDK to your Podfile:
pod'Rudder','~> 2.0.0'
Run the following command:
pod install
Add the SDK to your Cartfile:
github"rudderlabs/rudder-sdk-ios"
Then, run the following command:
carthage update
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:
@importRudder;
importRudder
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:
To add the RudderStack package in Xcode, follow these steps:
Go to File> Add Package.
In the search bar, enter the package repository git@github.com:rudderlabs/rudder-sdk-ios.git.
In Dependency Rule, select Up to Next Major Version and enter the value as 2.2.5:
Select the project to which you want to add the package and click Add Package.
To use the RudderStack Swift package, include the following snippet in your project:
// swift-tools-version:5.5// The swift-tools-version declares the minimum version of Swift required to build this package.importPackageDescriptionletpackage=Package(name:"RudderStack",products:[// Products define the executables and libraries a package produces, and make them visible to other packages..library(name:"RudderStack",targets:["RudderStack"]),],dependencies:[// Dependencies declare other packages that this package depends on..package(url:"git@github.com:rudderlabs/rudder-sdk-ios.git",from:"1.8.0")],targets:[// Targets are the basic building blocks of a package. A target can define a module or a test suite.// Targets can depend on other targets in this package, and on products in packages this package depends on..target(name:"RudderStack",dependencies:[.product(name:"Rudder",package:"rudder-sdk-ios")]),.testTarget(name:"RudderStackTests",dependencies:["RudderStack"]),])
Initializing the RudderStack client
To initialize the RudderStack client, place the following code in your AppDelegate file under the didFinishLaunchingWithOptions method:
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:
Parameter
Type
Description
Default value
logLevel
RSLogLevel
Controls how much of the log you want to see from the SDK.
RSLogLevel.none
dataPlaneUrl
String
Your data plane URL.
https://hosted.rudderlabs.com
flushQueueSize
Integer
Number of events in a batch request sent to the server.
30
dbCountThreshold
Integer
Number of events to be saved in the SQLite database. Once the limit is reached, older events are deleted from the database.
10000
sleepTimeout
Integer
Minimum waiting time to flush the events to the server.
10 seconds
trackLifecycleEvents
Boolean
Determines if the SDK will capture application life cycle events automatically.
true
autoSessionTracking
Boolean
Determines if the SDK automatically tracks user sessions. See Tracking user sessions for more information.
true
sessionTimeout
Integer
Maximum inactivity period before the session expires.
300000 ms (5 minutes)
recordScreenViews
Boolean
Determines if the SDK will capture will capture screen view events automatically.
false
controlPlaneUrl
String
This 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.
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.
OneTrust consent
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
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).
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.
RudderStack captures deviceId and uses that as anonymousId for identifying unknown users. This helps in tracking the users across the application installation.
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.
The screen method accepts the following parameters:
Name
Data type
Presence
Description
screenName
NSString
Required
Name of the screen viewed by the user.
properties
NSDictionary
Optional
Extra property object to be passed along with the screen call.
option
RSOption
Optional
Extra 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.
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.
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:
[[RSClientsharedInstance]setOptOutStatus:YES];
RSClient.sharedInstance().setOptOutStatus(true)
Once the user grants their consent, you can enable user tracking once again using the setOptOutStatus API by passing NO or false:
[[RSClientsharedInstance]setOptOutStatus:NO];
RSClient.sharedInstance().setOptOutStatus(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.
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:
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.
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:
RSOption*option=[[RSOptionalloc]init];//default value for `All` is true
[optionputIntegration:@"All"isEnabled:YES];// specifying destination by its display name
[optionputIntegration:@"Amplitude"isEnabled:YES];[optionputIntegration:@"<DESTINATION_DISPLAY_NAME>"isEnabled:<BOOLEAN>];
letoption:RSOption=RSOption();//default value for `All` is trueoption.putIntegration("All",isEnabled:true)// specifying destination by its display nameoption.putIntegration("Amplitude",isEnabled:true)option.putIntegration(<DESTINATION_DISPLAY_NAME>,isEnabled:<BOOLEAN>)
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.
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.
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:
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.
Create a RSCustomDestination.swift file by extending RSDestinationPlugin:
classRSCustomDestination:RSDestinationPlugin{varkey:String="Custom"varcontroller=RSController()vartype:PluginType=.destinationvarRSClient.sharedInstance():RSClient?funcupdate(serverConfig:RSServerConfig,type:UpdateType){guardtype==.initialelse{return}// Some code}functrack(message:TrackMessage)->TrackMessage?{// Some codereturnmessage}funcidentify(message:IdentifyMessage)->IdentifyMessage?{// Some codereturnmessage}funcscreen(message:ScreenMessage)->ScreenMessage?{// Some codereturnmessage}funcgroup(message:GroupMessage)->GroupMessage?{// Some codereturnmessage}funcalias(message:AliasMessage)->AliasMessage?{// Some codereturnmessage}funcflush(){// Some code}funcreset(){// Some code}}
Then, create a CustomDestination class file by extending RudderDestination and initialize RSCustomDestination inside init():
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.
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.
Finally, add the CustomDestination with the RudderStack iOS SDK after its initialization:
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.
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:
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 Name
Updated Name
RudderClient
RSClient
RudderConfig
RSConfig
RudderLogLevelDebug
RSLogLevelDebug
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:
lettraits=RSClient.sharedInstance().traits
NSDictionary*traits=[RSClientsharedInstance].traits;// or
NSDictionary*traits=[[RSClientsharedInstance]traits];
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.
Can I disable event tracking until the user gives their consent?
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.
This site uses cookies to improve your experience while you navigate through the website. Out of
these
cookies, the cookies that are categorized as necessary are stored on your browser as they are as
essential
for the working of basic functionalities of the website. We also use third-party cookies that
help
us
analyze and understand how you use this website. These cookies will be stored in your browser
only
with
your
consent. You also have the option to opt-out of these cookies. But opting out of some of these
cookies
may
have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This
category only includes cookies that ensures basic functionalities and security
features of the website. These cookies do not store any personal information.
This site uses cookies to improve your experience. If you want to
learn more about cookies and why we use them, visit our cookie
policy. We'll assume you're ok with this, but you can opt-out if you wish Cookie Settings.