How to test SKAdNetwork: Step-by-step instructions
Update: Originally published August 13, 2020. Updated most recently February 11, 2021 to reflect changes following the iOS 14 release and additional tips from Apple.
Since we announced our first-to-market support for SKAdNetwork and released our open-source code for its implementation, we’ve been collaborating with many advertisers, publishers, ad networks, and MMPs to integrate SKAdNetwork and start testing it.
We’ve received many questions and ideas in our Mobile Attribution Privacy (MAP) slack group, but one of the most common questions that I’ve personally been getting is how to test the framework and see actual postbacks from it – a task that many have been struggling with. Some have even started to suspect if it’s even working at all yet…
We can assure you that SKAdNetwork indeed works, and we’ve seen the live postbacks signed by Apple before our very eyes. And although it may be challenging to figure out initially, it’s definitely possible once you understand the details. So we wanted to share those tips to help you expedite the SKAdNetwork adoption and push the industry forward.
Important note:
If you’re an advertiser and a Singular client, then you don’t have to worry about any of this – we’ve got you covered. You simply need to upgrade to our latest SDK that we released as part of Singular’s SKAdNetwork solution, and we’ll make sure that SKAdNetwork works behind the scenes.
To start, here’s a quick recap of the documented steps to get a postback in iOS 14, as summarized by Apple here:
- The Ad Network registers to SKAdNetwork and provides a signed ad to the publisher app
- The publisher app displays the ad by calling the loadProduct(withParameters:completionBlock:) method. It also must have the ad network ID (all lowercase) in its Info.plist
- The advertiser app calls registerAppForAdNetworkAttribution() and optionally updates a conversion value using updateConversionValue(_:)
- Once the 24-48 hour timer expires, a postback should be sent directly from the device to the registered SKAdNetwork endpoint
Note: For iOS 11.3 to 13.x, the postback timer is between 1 minute to 2 hours.
Simple, right?
The problem starts when you don’t get the postback – you click the ad, download the app and launch it, wait for the timer to expire… and nothing. No error logs, no debugging tools, no way to know what went wrong. Try to repeat that process a few more times and it may drive you crazy.
But after running it again and again and using some intensive research tools, we’ve figured out all the necessary steps and summarized them all in the following definitive guide for how to get a live SKAdNetwork postback.
How to get a live SKAdNetwork postback
Step 1: Check your SKAdNetwork server endpoints
You need two endpoints to run an end-to-end test with SKAdNetwork:
- Ad Server – which generates the ad signatures and provides all the details to the publisher app
- Postback Server – which receives the signed postbacks from the device
The critical piece to note here is the Ad Server endpoint – your implementation should follow Apple’s steps for generating your signature very carefully because any small mistake or compatibility issue will cause the postback not to send.
A good practice here is to simulate how Apple would validate your signature – you can log the ad details just before displaying them, reconstruct the message, and validate its signature using your public key. We’ve noticed that when the generated signature was compatible with OpenSSL (by running the command-line below), that’s when we’ve passed that step successfully:
❯❯❯ openssl dgst -sha256 -verify public.pem -signature signature.bin message.bin
Verified OK
Step 2: Get a live Advertiser app in the App Store
This is probably intuitive since you have to provide an AppStore ID of a specific advertised app when calling loadProduct in the publisher app – you have to actually download the advertiser app from the production App Store to get an attributed postback.
Step 3: Get a live Publisher app
You can use a dev-signed Publisher app to test SKAdNetwork (loaded with Xcode to the device or distributed via TestFlight), and it doesn’t have to be live in the App Store to simulate a live postback.
Keep in mind that the source-app-id parameter in the SKAdNetwork v2.0 postback requires a production-signed app install – so if the publisher app isn’t downloaded from the App Store, the source-app-id parameter will always be 0.
Step 4: Get a physical device with the test profile
You will need a physical device to test SKAdNetwork since the iOS simulator doesn’t have access to the App Store.
Apple has released an SKAdNetwork Profile that you can install on your test device to reduce the postback timers from 24-48 hours to 5-10 minutes. This is very useful for debugging purposes. You can download it from your Apple developer account here:
Now, an important point worth highlighting is that SKAdNetwork has been supported since iOS 11.3, but support for redownloads has only been added in iOS 14 in Version 2.0. So if you’re testing a device with iOS 13, the postback will only be sent following the first install of the advertiser app.
The Ultimate SKAdNetwork Troubleshooting Guide
To summarize, here are some troubleshooting tips that may be useful to save you some debugging time:
- First, double-check the Info.plist file in your publisher app, and make sure you have the ad network ID listed in lowercase.
- Ensure that the loadProduct parameters are exactly what you’ve generated and signed in the Ad Server, since it can easily break if any of the parameters changed on their way. A good test would be to log the parameters just before displaying the ad and simulate Apple’s validation logic using your public key.
- If you’re testing SKAdNetwork v1.0 on a pre-iOS 14 device, make sure this is the first time that this iTunes user has ever downloaded the advertised app. If not, you won’t be able to get its postback.
- Keep in mind that it can take up to 48 hours to receive a postback from the device starting from the registerAppForAdNetworkAttribution() call or last updateConversionValue(_:) call. You can install Apple’s SKAdNetwork Profile to reduce the timer for debugging purposes.
- Remember that the postback should always be sent directly from the device to the registered SKAdNetwork endpoint, but it will only include the conversion value and publisher ID in Version 2.0 if the parameters meet Apple’s privacy thresholds. If your publisher app is dev-signed, then Apple will ignore the privacy thresholds (identifying that this is a test) and always send the postback with source-app-id as 0 (zero).
- New: ensure that your timestamps are in milliseconds, not seconds, or SKAdNetwork postbacks will not be sent. This is what Apple calls the key that represents the timestamp of an ad impression. It’s in UNIX format but based on milliseconds, not seconds as epoch is usually treated (which may be unintuitive). A brand we talked to set their timestamp in seconds and continually failed to receive postbacks until they updated to milliseconds.
Any questions or other recommendations? Send us feedback in our MAP Slack group, and we’ll update this post with new learnings!
Looks a bit daunting? Don’t worry! If you’re an advertiser, then it’s our job as an MMP to provide you a full solution using a simple SDK upgrade. Click here to schedule a call with our product team.
And if you’re an ad network, check our latest post on how to support the Secure SKAdNetwork solution with almost no effort!