This content originally appeared on DEV Community and was authored by ArshTechPro
Apple continues to prioritize user privacy while enabling effective advertising attribution. At WWDC 2024, Apple introduced AdAttributionKit, a new framework for iOS and iPadOS that builds upon the fundamentals of SKAdNetwork. This comprehensive guide explores the framework’s capabilities, implementation details, and what it means for developers and advertisers.
Understanding Privacy-Preserving Ad Attribution
At the heart of AdAttributionKit lies the concept of crowd anonymity. This privacy-preserving mechanism intelligently adjusts the amount of data sent to ad networks based on conversion volumes:
- Low conversion volumes: Less data is shared to protect individual user privacy
- Medium conversion volumes: Moderate data sharing as the crowd grows
- High conversion volumes: Maximum data sharing when anonymity is preserved through crowd size
This approach ensures that individual users cannot be identified while still providing valuable attribution data to advertisers.
The Ad Attribution Flow
The attribution process follows a clear path:
- Ad networks generate, sign, and serve ads to publisher apps
- Publisher apps display these ads to users
- Users install the advertised app
- As users engage with the app over time, conversion data is collected
- After the measurement period, postbacks containing conversion information are sent to the ad network
Working with Ad Impressions
The New Ad Format
AdAttributionKit introduces a compact JWS (JSON Web Signature) format for ad impressions. Key fields include:
- advertised-item-identifier: The App ID of the advertised app
- publisher-item-identifier: The App ID of the app displaying the ad
- source-identifier: A 4-digit integer representing campaign information (maintaining compatibility with SKAdNetwork 4.0)
Creating App Impressions
Implementation is straightforward:
// Fetch the ad's compact JWS representation
let jwsString = fetchAdImpressionJWS()
// Create an AppImpression instance
let appImpression = AppImpression(jwsRepresentation: jwsString)
Displaying Ads: Three Approaches
AdAttributionKit supports three distinct methods for displaying advertisements:
1. Custom Click Ads
These are clickable creative ads that navigate users to a marketplace for app installation. Implementation requires:
// Create the custom ad view
let customAdView = createCustomAdView()
// Add UIEventAttributionView on top
let eventAttributionView = UIEventAttributionView()
customAdView.addSubview(eventAttributionView)
// Handle tap events
func handleAdTap() {
appImpression.handleTap()
}
Important: The handleTap()
method must be called within 15 minutes of AppImpression initialization.
2. View-Through Ads
Perfect for video ads or other custom presentations:
// When ad presentation starts
appImpression.beginView()
// When ad presentation ends (minimum 2 seconds later)
appImpression.endView()
Key requirements:
- Minimum 2-second display duration
- Balanced begin/end calls on the same instance
- No overlapping view-through presentations for the same advertised app
3. Native iOS Components
SKOverlay: Appears as a banner within the app context
let configuration = AppConfiguration()
configuration.appImpression = appImpression
// Configure and present SKOverlay
SKStoreProductViewController: Full-screen presentation
storeViewController.loadProduct(
withParameters: parameters,
impression: appImpression
)
Understanding Postbacks
Postbacks are the conversion signals sent to ad networks, containing both signed and unsigned components.
Signed Postback Fields
- conversion-type: Indicates download, redownload, or re-engagement
- marketplace-identifier: Where the conversion occurred (e.g., “com.apple.AppStore”)
- publisher-item-identifier: The app that showed the original ad (crowd anonymity dependent)
- source-identifier: 2-4 digits based on crowd anonymity levels
Unsigned Fields
- ad-interaction-type: “click” or “view”
- conversion-value: Fine-grained value (0-63) or coarse value (low/medium/high)
Measuring User Engagement with Conversion Values
Conversion values help measure advertising effectiveness and calculate return on ad spend (ROAS). Here’s how to update them:
// Account creation - moderate value event
let accountCreationUpdate = PostbackUpdate(
fineConversionValue: 20,
lockPostback: false,
coarseConversionValue: .low
)
Postback.updateConversionValue(accountCreationUpdate)
// First video watched - higher value
let videoWatchUpdate = PostbackUpdate(
fineConversionValue: 38,
lockPostback: false,
coarseConversionValue: .medium
)
Postback.updateConversionValue(videoWatchUpdate)
// Video uploaded - highest value, lock the postback
let videoUploadUpdate = PostbackUpdate(
fineConversionValue: 42,
lockPostback: true,
coarseConversionValue: .high
)
Postback.updateConversionValue(videoUploadUpdate)
The lockPostback
parameter freezes the postback for immediate scheduling when high-value events occur.
Re-engagement: Bringing Users Back
AdAttributionKit introduces re-engagement campaigns to recover dormant users. To enable re-engagement:
- Add
"eligible-for-re-engagement": true
to the ad impression payload - Handle re-engagement with universal links:
let reengagementURL = URL(string: "myapp://special-offer")!
appImpression.handleTap(reengagementURL: reengagementURL)
AdAttributionKit appends a query parameter to help apps identify re-engagement opens.
Selective Postback Updates
Target specific conversion types:
// Update only re-engagement postbacks
let reengagementUpdate = PostbackUpdate(
fineConversionValue: 25,
lockPostback: false,
coarseConversionValue: .medium,
conversionTypes: [.reengagement]
)
// Update only install postbacks
let installUpdate = PostbackUpdate(
fineConversionValue: 30,
lockPostback: false,
coarseConversionValue: .medium,
conversionTypes: [.install]
)
Testing with Developer Mode
AdAttributionKit’s asynchronous nature and privacy-preserving time randomization can make testing challenging. Developer Mode addresses this by:
- Removing time randomization for deterministic behavior
- Shortening conversion windows for faster testing cycles
- Accelerating postback transmission
To enable Developer Mode:
- Navigate to Settings → Developer
- Toggle “AdAttributionKit Developer Mode”
Migration and Interoperability
Good news for existing SKAdNetwork users:
- Full interoperability with SKAdNetwork
- No re-enrollment required for registered ad networks
- Gradual migration path available
Next Steps for Implementation
For Ad Networks:
- Serve ads in the new JWS format
- Display ads using AdAttributionKit APIs
- Update server infrastructure to receive and parse new postback formats
For App Developers:
- Integrate AdAttributionKit APIs for conversion value updates
- Implement appropriate ad display methods
- Test thoroughly using Developer Mode
Conclusion
AdAttributionKit represents a significant evolution in privacy-preserving ad attribution on iOS. By building on SKAdNetwork’s foundation while introducing new capabilities like re-engagement and improved testing tools, Apple continues to balance user privacy with the advertising ecosystem’s needs.
For detailed implementation guidance and API references, developers should consult Apple’s official AdAttributionKit documentation and explore the framework’s capabilities in their development environments.
This content originally appeared on DEV Community and was authored by ArshTechPro