WWDC – AdAttributionKit Explained: Building on SKAdNetwork’s Foundation



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:

  1. Ad networks generate, sign, and serve ads to publisher apps
  2. Publisher apps display these ads to users
  3. Users install the advertised app
  4. As users engage with the app over time, conversion data is collected
  5. 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:

  1. Add "eligible-for-re-engagement": true to the ad impression payload
  2. 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:

  1. Navigate to Settings → Developer
  2. 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:

  1. Serve ads in the new JWS format
  2. Display ads using AdAttributionKit APIs
  3. Update server infrastructure to receive and parse new postback formats

For App Developers:

  1. Integrate AdAttributionKit APIs for conversion value updates
  2. Implement appropriate ad display methods
  3. 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