[NEW] iOS SDK: Adding SKAdNetwork Support

Singular iOS SDK
Singular iOS SDK version 10.1.2
Compatibility iOS 8+
Sample App

Our sample app includes a complete integration of the Singular SDK. Review the code to see how the different parts of the integration come together using best practices.

Integration Guides
  1. Basic Integration
  2. Tracking Events and Revenue
  3. Implementing Deep Links
  4. Adding SKAdNetwork Support
  5. Advanced Options


Introduction: SKAdNetwork and SKAN

SKAdNetwork is Apple's new framework for determining mobile install attribution without compromising the end user's privacy. SKAdNetwork lets you measure the performance of your app marketing campaigns without sharing the user's personally identifiable information.

Singular's new version of the iOS SDK helps you implement SKAdNetwork seamlessly and with minimal engineering effort.

This SKAdNetwork implementation is based on SKAN - a standard developed by Singular for a smooth implementation of SKAdNetwork. To learn more about SKAN, see the SKAN spec released in July 2020.

Note: iOS 14 is still in beta. While we don't expect major changes in future SDK versions, we keep monitoring Apple's release notes and making changes when needed, and we do expect some incremental updates to our SDK before the final iOS 14 release.

Enabling SKAdNetwork Tracking

To enable SKAdNetwork tracking for your app, turn on the skAdNetorkEnabled configuration option before initializing Singular:

// instantiate SingularConfig
SingularConfig* config = [[SingularConfig alloc] initWithApiKey:apiKey andSecret:secretKey];
// add the skAdNetworkEnabled option and set it to YES
config.skAdNetworkEnabled = YES;
// start
[Singular start:config];

Handling Conversion Value Updates

Managed Mode

By default, the SKAdNetwork implementation manages the conversion value directly from the Singular server side.

This allows for maximum flexibility as you can set and change your conversion values through the Singular web app, without modifying your client-side code.

This server-side managed mode also helps you deal with the SKAdNetwork timers. SKAdNetwork allows you to update the conversion value within 24 hours from the time of registration to SKAdNetwork. Any call to update the conversion value extends the timer by 24 more hours. Therefore, when choosing your conversion events, you'll have to make sure the events happen within that update window. In managed mode, you can change the conversion event configuration at any time, without releasing a new version of your app.

Manual Mode

If you want to update the conversion value on your own in the app code, set manualSkanConversionManagement to YES when you initialize the SDK:

SingularConfig* config = 
[[SingularConfig alloc] initWithApiKey:apiKey andSecret:secretKey];
// Enable SKAdNetwork config.skAdNetworkEnabled = YES;
// Enable manual conversion value updates config.manualSkanConversionManagement = YES;
[Singular start:config];

Then, to update the conversion value, use the skanUpdateConversionValue method wherever needed in your app's lifecycle:

skanUpdateConversionValue Method (Objective-C)
Description Manually update the SKAdNetwork conversion value.
Signature + (BOOL)skanUpdateConversionValue:(NSInteger)conversionValue;
Usage Example
// signup event happened
[Singular event:@"SignUp"];
// update conversion value to 7 [Singular skanUpdateConversionValue:7];

Note: The skanUpdateConversionValue method will not function if you have not set manual updates to "yes". 

Retrieving the Conversion Value

To get the current conversion value, use the skanGetConversionValue method. This method works in both managed and manual mode.

skanGetConversionValue Method (Objective-C)
Description Get the current conversion value tracked by the Singular SDK.
Signature + (NSNumber *)skanGetConversionValue;
Usage Example
NSNumber* conversionValue = [Singular skanGetConversionValue];

Advanced Options

Delaying the Registration for SKAdNetwork

If you don't want to register for SKAdNetwork tracking right when you initialize the SDK, but at a later point in the app lifecycle, you can initialize the SDK with skAdNetworkEnabled = "no". Then, to register for SKAdNetwork, use the skanRegisterAppForAdNetworkAttribution method:

skanRegisterAppForAdNetworkAttribution Method (Objective-C) 
Description Register for SKAdNetwork tracking.
Signature + (void)skanRegisterAppForAdNetworkAttribution;
Usage Example
// Instantiate SingularConfig
SingularConfig* config = [[SingularConfig
alloc] initWithApiKey:apiKey andSecret:secretKey];
// Disable SKAdNetwork registration config.skAdNetworkEnabled = NO;
// start [Singular start:config];
// Later on - register for SKAdNetwork [Singular skanRegisterAppForAdNetworkAttribution];

Other iOS 14 Updates

AppTrackingTransparency Consent Handling

Note: On September 3rd, Apple announced an update delaying certain privacy features on iOS 14, specifically removing the requirements to use AppTrackingTransparency to access the IDFA until "early next year".  With this change, we recommend NOT implementing the AppTrackingTransprency pop-up with the iOS 14 launch, as IDFA is still accessible as of iOS 14 beta 7.  Read more about iOS 14 beta 7 and the IDFA here

The below content is still available for the future unannounced version of iOS 14, where AppTrackingTransparency will be required before the IDFA can be retrieved.

Another major change in iOS 14 is that you are now required to ask for user consent (using the App Tracking Transparency framework) before you can access some user data - including using the device's IDFA value.

Singular strongly benefits from having the IDFA to identify devices and perform install attribution. If Singular doesn't have the device's IDFA, it can still perform probabilistic attribution (learn more). However, since identifier-based attribution is more accurate, we want to take advantage of the IDFA whenever we can.

For that purpose, you should ask for consent to get the IDFA and retrieve it before the Singular SDK sends a user session to the Singular servers. Once the SDK fires a session, it triggers Singular's install attribution process - based only on the data that is available to Singular at that point.

To delay the SDK from firing a session, you can initialize the Singular SDK with the waitForTrackingAuthorizationWithTimeoutInterval option (see sample code below).

  1. The SDK will start recording a session and user events but will not send them to the Singular server yet.
  2. As soon as App Tracking Transparency consent is granted/denied, or the set time elapses, the SDK will send the session and any queued events to the Singular server (with or without the IDFA).
  3. Singular will then start the attribution process, taking advantage of the IDFA if it is available, or using probabilistic attribution if the IDFA is not available.

Sample code:

SingularConfig* config = 
[[SingularConfig alloc] initWithApiKey:apiKey andSecret:secretKey];
// Register for SKAdNetwork tracking config.skAdNetworkEnabled = YES
// Wait 5m for tracking authorization before sending any events config.waitForTrackingAuthorizationWithTimeoutInterval = 300
// start [Singular start:config];
// call requestTrackingAuthorizationWithCompletionHandler
// from ATTrackingManager to start the user consent process [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:
^(ATTrackingManagerAuthorizationStatus status){     // your authorization handler here     // note: the Singular SDK will automatically detect if authorization
// has been given and initialize itself }];

The following table summarizes the possible scenarios using this integration:

Scenario IDFA Availability
User sees the consent dialog and grants consent before the set time elapses IDFA is available
User sees the consent dialog and denies consent before the set time elapses IDFA is not available
The set time expires, then the user is shown the consent dialog and grants consent IDFA is available only for the user events that are reported after the consent is granted
The set time expires, then the user is shown the consent dialog and denies consent IDFA is not available
The user is shown the consent dialog, exits the app without taking action, and later opens the app and grants consent after the set time has expired Any queued events are sent to the Singular server when the app is reopened. The IDFA is not available for these events. Any events tracked after consent is granted do have IDFA associated with them.
The user is shown the consent dialog, exits the app without taking action, and later opens the app and denies consent Any queued events are sent to the Singular servers when the app is reopened. The IDFA is not available for these events or any of the events tracked afterwards.
Was this article helpful?