SKAdNetwork Setup for iOS Install Attribution
After iOS 14.5 Apple removed direct IDFA access without explicit user consent. Instead of deterministic attribution through ad identifier, Apple introduced SKAdNetwork—an aggregated mechanism where postbacks go directly to ad networks without device data transmission. Setting this up isn't complicated—but understanding what exactly to do and in which order takes time.
How SKAdNetwork Works
Attribution chain looks like:
- Ad network signs ad impression with its SKAdNetwork ID
- User clicks and installs app
- iOS registers install and starts timer
- App calls
updateConversionValue(_:)—passes 6-bit value (0–63) encoding user action - Apple sends postback to ad network—no user_id, no IDFA, only aggregate campaign data
Postback delay is 24–72 hours. This isn't a bug—it's Apple's architectural decision to protect privacy.
What You Need to Do in App
Add SKAdNetwork IDs to Info.plist
Each ad network has unique SKAdNetwork ID. List them in your app's Info.plist—otherwise Apple won't credit attribution from that network:
<key>SKAdNetworkItems</key>
<array>
<!-- Google UAC -->
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
<!-- Meta (Facebook) -->
<dict>
<key>SKAdNetworkIdentifier</key>
<string>v9wttpbfk9.skadnetwork</string>
</dict>
<!-- TikTok -->
<dict>
<key>SKAdNetworkIdentifier</key>
<string>gta9lk7p23.skadnetwork</string>
</dict>
<!-- AppLovin -->
<dict>
<key>SKAdNetworkIdentifier</key>
<string>ludvb6z3bs.skadnetwork</string>
</dict>
</array>
MMP providers (AppsFlyer, Adjust) maintain current list of 200+ identifiers—export as plist fragment.
Call updateConversionValue
This is the trickiest part. You have 6 bits (value 0–63) to encode user behavior. Apple resets the 24-hour timer each time you call updateConversionValue with higher value. After timer expires—postback sends, value locks.
import StoreKit
// Example simple conversion schema:
// 0–7: registration (bit 0 = completed onboarding)
// 8–15: first action (bit 3 = added to cart)
// 16–31: purchase (bit 4 = made purchase)
func trackRegistration() {
if #available(iOS 14.0, *) {
SKAdNetwork.updateConversionValue(1) // 000001
}
}
func trackFirstPurchase(revenueLevel: Int) {
// revenueLevel 1–3 encode into bits 1-2
let value = 16 | revenueLevel // 010001, 010010, 010011
if #available(iOS 14.0, *) {
SKAdNetwork.updateConversionValue(value)
}
}
Rule: value must be strictly increasing. Calling updateConversionValue(5) after updateConversionValue(10) is ignored. This limitation applies to SKAdNetwork 1.0–2.x.
Conversion Value Schema: Pack Maximum Meaning into 6 Bits
Standard approach—divide 6 bits into two fields:
| Bits | Purpose | Example Values |
|---|---|---|
| 5–4 (high) | Event trigger | 00=install, 01=registration, 10=first_purchase, 11=repeat_purchase |
| 3–0 (low) | Revenue bucket | 0=$0, 1=$0–5, 2=$5–20, 3=$20–50, ..., 15=$500+ |
With this schema ad network doesn't just get "install"—it gets "user made first purchase in $5–20 range." Google UAC can optimize toward such users.
Common Mistakes
Missing SKAdNetwork IDs. If network ID absent from Info.plist—Apple won't send postback and attribution from that network doesn't work. Ad network sees installs as unattributed.
Conversion value not updating. Many teams call SKAdNetwork.registerAppForAdNetworkAttribution() (obsolete SKAdNetwork 1.0 method) and forget updateConversionValue. Postback sends with zero value—ad network knows about install but not user activity.
Conversion value schema not aligned with ad team. Technical integration done, but marketing doesn't know what value 17 means in postback. Conversion value decoding needs documentation and setup in MMP dashboard.
What's Included
- Collect current SKAdNetwork ID list for used ad networks
- Design conversion value schema for product events
- Integrate
updateConversionValueat key app points - Configure decoding in AppsFlyer / Adjust
- Test via SKAdNetwork TestKit
Timeline
3–5 days including conversion value schema design and testing. Cost calculated individually after analyzing ad channels.







