One month before the release of iOS 14, there are still many speculations around what’s happening next for MMPs. How much will their role change? Are advertisers still ok paying 1-5 cents for each paid tracked install on iOS, even though it no longer has user-level granularity? Will Apple allow MMPs to validate Conversion Values though it wasn't mentioned in any Apple documentation? While those questions are unclear, we decided to tackle things that developers can do today, without the involvement of MMPs.
We sat down with the co-founder of the mobile growth agency 2ndPotion, Kevin Bravo, to talk about things that developers can utilize right now that are documented by Apple. Kevin created the first open-source solution that interacts with Apple’s SKAdNetwork called Elixir, so we know he's perfect for this sort of conversation.
Here is what we will cover today with Kevin.
1) For developers and game designers, iOS pop-up asks for consent to share the user’s IDFA - AppTrackingTransparency method.
2) For developers, an overview of the new attribution framework from Apple - SKAdNetwork.
2.1) For developers, attribution of installs - integrate registerAppForAdNetworkAttribution() method
2.2) For developers, attribute post-install events - integrate updateConversionValue(_:) method
2.3) For UA managers, understand how Apple reports installs and post-install events to ad network - Postbacks and timers
3) For the whole team to brainstorm, what could be better - Best Practices & Current Pain points
1) Asking users to share their IDFA - Integrating ApptrackingTransparency
Kevin: AppTrackingTransparency is a framework available for iOS 14 that allows app developers to ask permission to track the user. This permission is required to access the user's IDFA for attribution purposes.
Integrating it and using it will require you to prompt the user to access their IDFA with this popup:
If the user accepts tracking, you'll have the ability to request their IDFA. Otherwise, the IDFA will be 0000-0000-0000-0000.
Keep in mind that you won't be able to ask permission if the user is LAT (Limited Ad Tracking) ON.
Q: How many times can I show native popup?
Kevin: You can only show it only once per device.
Q: Can I ask for user consent again if it's rejected initially?
Kevin: If the user already saw this popup, you won't be able to display it again.
Q: Can I show my custom popup before the native one?
Kevin: You can decide when you will display this pop-up, which means that you're allowed to post an additional pop up before.
This way, you can decide to show the permission popup only if the user said yes to your custom one.
This strategy is already used by many companies to push notifications requests and will help allow you to have a 2nd opportunity to ask for permission.
Q: What happens if an app developer does not integrate AppTrackingTransparency?
Kevin: If you don't want/need to request the IDFA, you can decide not to display this popup.
This means that you won't have access to their IDFA (it will display as 0000-0000-0000-0000) and that ad networks won't have access to it as well.
2) Overview of the new attribution framework from Apple - SKAdNetwork
Kevin: Apple provides an anonymized attribution solution called SKADNetwork, enabling apps to keep tracking installs coming from different ad networks, without compromising users' anonymity.
When using SKADNetwork, a signature is attached to each ad click. When the user opens your app for the first time, Apple will be able to verify if they're coming from a specific ad with this signature.
Then, a postback is sent back to the ad network to attribute a new install.
The signature doesn't contain any identification data, keeping privacy at maximum by making it impossible to attach an install to a specific user.
To integrate SKADNetwork, you need to call two methods:
- registerAppForAdNetworkAttribution(): This method should be called at first launch and register the user for attribution. If the user is from a signed ad, a postback will be fired in the following hours, notifying the ad network of this app install.
- updateConversionValue(_:) This method should be called every time you want to update the conversion value attached to this specific user. You can call this method as many times as you want, but the conversion value will only be updated if it is higher than the previous one.
For ad monetization, developers need to determine, in advance, the ad networks they are going to use for monetization, and specify them inside their app via plist as it's specified in this documentation.
2.1) Attribute Installs - Integrate of registerAppForAdNetworkAttribution
Kevin: By calling registerAppForAdNetworkAttribution at first app launch, you're doing everything required to enable app install attribution with SKADNetwork.
However, the install attribution will only be possible if the ad network is signing their ads with SKADNetwork.
For advertising, developers need to ensure that ad networks have SKADNetwork integrated on their side to enable attribution and postbacks.
To make things easier, a list of all available ad network IDs is available here.
2.2) Attribute post-install events - Integrate updateConversionValue(_:)
Kevin: You can assign a conversion value to a specific install. This is a numeric value between 0 and 63.
It's a "signal" that will help you understand how valuable this specific user is, without giving you a way to identify them.
Ad networks can use this information to understand how valuable each install is for your business. This signal can help ad networks identify better audiences to serve your ads and improve your campaigns' performances.
Q: When should you use updateConversionValue(_:)?
Kevin: Conversion value can be updated multiple times for the same user, but there are some limitations:
- You can only update the conversion value with a higher value than your previous call (1-> 2 but not 3->2)
- A limited value between 0-63
You want to use conversion values because it delivers valuable signals to your ad networks. It will also allow you to
- Analyze essential behavior in the app after installing from a specific campaign/channel/country
- Offer additional data points to the ad network you can use to identify valuable cohorts for your game and optimize your campaigns’ performance.
You want to think about how you will define each conversion value to get the most out of SKADNetwork.
There are different approaches to conversion values management:
- Track revenue
- e.g., Conversion value 1 is .1 EUR, 50 is 5.0 EUR
- Track events
- e.g., level1_completed = conversion value 1
- Track revenue and progress events
- e.g., Conversion value 10 = lvl5_completed and spend 1EUR
For the Revenue + progress events, I created a conversion table that allows you to define each event you'll track and understand the conversion value you'll be sending.
As you'll see in the spreadsheet, we're using binaries to convert events to conversion values:
- Each conversion value translates to a set of 6 binary values.
- The first 3 binary values represent the revenue for this specific user (e.g., purchase > 10$ = "101")
- The last 3 binary values represent progress (e.g., 10 levels completed = "011")
- By combining the two sets of binary values, we get a conversion value (e.g., "101001" converts to the conversion value 43)
You can find the spreadsheet here:
Q: What is Elixir, and how does it help?
Kevin: Conversion values can only be sent from the app, making it complex to adjust the way you track conversion values without updating it.
Elixir is an open-source SDK that allows you to define and update your conversion values without updating the app after each change.
The way it works:
- You define your conversion table using one of the approaches available (revenue / mixed / progress)
- You store it on your server as a JSON
- You integrate Elixir SDK, tracking all the events available in the app
- At first launch, Elixir SDK will request the JSON, and match conversion values to actions taken by the user in real-time
- Elixir SDK will update the conversionValue based on the table you created
You can see an example of conversion table JSON. This is the document that Elixir read to generate the conversion value to track after each user's actions.
Currently, there is only one type of table available (link to the table) for Elixir. As developers collaborate on the project, every model will be easily covered (ad revenue binary, timestamp, geo, etc.)
2.3) Understand how Apple reports installs and post-install events to ad network - Postbacks and timers
Q: Can you explain how the postbacks timer work in updateConversionValue(_:)?
Kevin: There is additional complexity on the way postbacks are scheduled.
Two timers occur as follow:
- 24 hours timer: can be reset multiple times and has a defined duration of 24 hours
- Random timer: once it starts, it can't reset. The duration is random, between 0-24hours
When you fire registerAppForAdNetworkAttribution(), the 24 hours timer starts. If you decide to fire updateConversionValue(_:), timer 1 is reset to zero and starts again.
Every time you fire updateConversionValue(_:), 24 hours timer will reset.
Suppose you don't fire updateConversionValue(_:) before 24 hours timer expires, a random timer will start. Once the random timer starts, you can't update the conversion value anymore.
At the end of the random timer, the postback is sent to the ad network. This postback can include (or not) a conversion value (it will be the latest value you set for this specific user)
Apple documentation doesn't specify a time or occurrences limit on updateConversionValue. It means that, as long as the user comes every 24hours, you can send a new conversionValue up to 63 times (based on the limitations described in ‘When should you use updateConversionValue(_:)?’ question ).
Q: What data are ad networks receiving from SKADNetwork?
Kevin: Ad networks will receive a postback for each install that looks like this:
Some values are optional (e.g., conversion value) and may not be included in the postback.
More details about this postback and how ad networks can verify the authenticity of each install are here.
3) Best practices and existing pain points
Q: What are your recommendations when using updateConversionValue(_:)?
Kevin: You need to determine the most valuable actions that users can do in their first session and the following 1 to 3 days.
A valuable event gives you a good indication of users' engagement within your app. Purchase being the highest signal you can get.
Then, you should order events from the lowest signal to the highest. This list of events will help you define the conversion table.
Q: What are other pain points that developers might face when working with SKAdNetwork?
Kevin: There are different challenges that you'll face when working with SKADNetwork:
- Managing install timestamp: SKADNetwork randomizes the time when the postback is sent to the ad network, and there is no installation timestamp included. This makes it complicated to determine when the install occurs. It even gets harder if you decide to send conversion values after the first 24 hours.
The longer you wait before stopping to update conversion values, the broader the install time window gets.
One solution could be to use some of the conversion value bits to define the install day and limit the number of days when you'll update the conversion value (e.g., three days).
- Getting data back / verifying signatures: Currently, only ad networks will have access to install postbacks. It is still unclear which ad networks will enable advertisers to get access to SKADNetwork data. Requesting this data will be vital as you'll be able to verify installs authenticity with a signature.
- Managing IDFA attribution + SKADNetwork: How do you work with SKADNetwork and keep measuring user-level attribution opted in for the IDFA tracking? This mixed model will be complex and will require an excellent workflow to avoid dedupe install logs.