+2 votes
by (13.7k points)

1 Answer

+1 vote

The timer logic introduced to the postback mechanism in SKAdNetwork 2.0 is convoluted and confusing. I'll attempt to explain it below, but this article should be seen as necessary background in understanding the SKAdNetwork postback.

Conversion Value

Conversion Value is a parameter that was added to the SKAdNetwork 2.0 postback that is sent from Apple to the ad network that sourced the user to the app. The conversion value is a 6-bit value; a 6-bit value is a sequence of six characters, each of which can only contain either a 0 or 1. A 6-bit value can take 64 different values (2^6 = 64).

The highest possible value for a 6-bit value is 111111. The lowest possible value for a 6-bit value is 000000. To understand how 6-bit values "ascend," or increment, see this article. Essentially, a bit is either "on" (raised to the 1st power) or "off" (raised to the 0th power, meaning 0), and the underlying potential value of each character is double the potential value of the character to its right, starting from 1 at the very far right. The integer value of any bit value is the sum of the corresponding integer values of all bits. 


A 1-bit character can either correspond to an integer value of 1 (1^1) or 0 (1^0).

But a 2-bit character can correspond to four potential integer values: 

  1. 00 (2^0 + 1^0) = 0
  2. 01 (2^0 + 1^1) = 1
  3. 10 (2^1 + 1^0) = 2
  4. 11 (2^1 + 1^1) = 3

The integer value 7 is represented with a 3-bit value as: 111 (4^1 + 2^1 + 1^1). The integer value 25 is represented with a 5-bit value as: 11001 (16^1 + 8^1 + 4^0 + 2^0 + 1^1).

The 6-bit value can have 64 of these values, corresponding to integer values 0-63. 

Postback Timer

If the developer wants to include a conversion value in its SKAdNetwork postback to the ad network that supplied the user, they should invoke the updateConversionValue() method at app open. Once this method is invoked, a resettable 24-hour timer is started -- when this timer expires, the postback is fired to the ad network.

The 24-hour timer is reset each time the updateConversionValue() method is fired with a 6-bit value that is higher than the 6-bit value currently recorded (or if a 6-bit value is being provided for the first time after app open). From the documentation:


If updateConversionValue() is called with the same 6-bit conversion value as is currently recorded, or with a lower valued 6-bit conversion value than is currently recorded, then the 24-hour timer does not reset. And calls to updateConversionValue() after the postback has been sent do nothing.

Once the 24-hour timer expires, a second, random timer of less than 24 hours starts. This timer is not resettable and is only meant to obfuscate the process such that the app developer won't be able to map a received conversion value at a network with a user who took the action mapped to that conversion value at a specific time.

A few things to note here:

  • The SKAdNetwork postback does not include a date parameter, so the ad network receiving these postbacks doesn't know when the user was acquired upon receipt of their postback, and it also doesn't know when the conversion value event was recorded (because of the obfuscation timer);
  • Only one postback is ever sent. No subsequent conversion values are sent to the network after the install attribution postback is sent.

The conversion value is an arbitrary mapping that the developer can attach to anything in the app: to a specific event being trigger by the user (eg. complete level 7, finish tutorial, make payment, etc.), or to some imputed LTV of the user at that time, etc. Managing conversion values will be a central component of advertising strategy in iOS14.

by (13.7k points)
Am I right, that it means we can postpone the event window from 24 hours to up to 64 days if we will daily send fake events and use only 111111 as an important event for us? That could help for App developers with long lifetime and let's say mark distinguish bad vs good users by this technique.
updateConversionValue() has to be called from within the client, it can't be called server-side. So assuming the user opened the app every day, then yes, you could delay the event being sent for 64 days.