npx skills add ...
npx skills add dpearson2699/swift-ios-skills --skill adattributionkit
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing SKAdNetwork with AdAttributionKit for ad measurement.
npx skills add dpearson2699/swift-ios-skills --skill adattributionkit
Privacy-preserving ad attribution for iOS 17.4+. AdAttributionKit lets ad networks measure conversions (installs and re-engagements) without exposing user-level data. It supports the App Store and alternative marketplaces, and interoperates with SKAdNetwork.
Three roles exist in the attribution flow: the ad network (signs impressions, receives postbacks), the publisher app (displays ads), and the advertised app (the app being promoted).
AdAttributionKit preserves user privacy through several mechanisms:
In migration and interoperability reviews, explicitly state that the system evaluates AdAttributionKit and SKAdNetwork impressions together, only one impression wins per conversion, click-through beats view-through, and recency breaks ties within click-through impressions before falling back to the most recent view-through impression.
A publisher app displays ads from registered ad networks. Add each ad network's ID to the app's Info.plist so its impressions qualify for install validation.
Ad network IDs must be lowercase. SKAdNetwork IDs (ending in .skadnetwork)
are also accepted -- the frameworks share IDs.
For click-through custom-rendered ads, place one UIEventAttributionView over
each tappable ad/control. It must cover the tappable area and stay above views
that would intercept touches before handleTap() succeeds.
The advertised app is the app someone installs or re-engages with after seeing an ad. It must call a conversion value update at least once to begin the postback conversion window.
Add AttributionCopyEndpoint under the top-level AdAttributionKit Info.plist
dictionary so the device sends a copy of the winning postback to your server:
The system derives the well-known endpoint from the registrable domain in the URL, ignoring subdomains:
Configure your server to accept HTTPS POST requests at that path. The domain must have a valid SSL certificate.
Add a second key in the same AdAttributionKit dictionary to also receive
copies of winning re-engagement postbacks:
Call a conversion value update as early as possible after first launch to begin the conversion window:
Ad networks create signed impressions using JWS (JSON Web Signature). The
publisher app uses AppImpression to register and handle those impressions.
The JWS contains the ad network ID, advertised item ID, publisher item ID, source identifier, timestamp, and optional re-engagement eligibility flag. See references/adattributionkit-patterns.md for JWS generation details.
Record a view impression when the ad content has been displayed and dismissed:
For long-lived ad views, use beginView() and endView() to track view
duration:
Respond to ad taps by calling handleTap() within 15 minutes of creating the
AppImpression; otherwise request a fresh impression. If the advertised app is
not installed, the system opens its App Store or marketplace page. If installed,
the system launches it directly.
A UIEventAttributionView must overlay the ad for handleTap() to succeed.
Pass the impression to StoreKit overlay or product view controller APIs. StoreKit automatically records view-through impressions after 2 seconds of display and click-through impressions on tap.
Postbacks are attribution reports the device sends to ad networks (and optionally to the advertised app developer) after a conversion event.
Winning attributions can produce multiple postbacks across conversion windows; lower data tiers and nonwinning attributions disclose less. Load references/adattributionkit-patterns.md for the current window and delay matrix.
Attribution eligibility windows are distinct from conversion/postback windows. Configure and verify view-through, click-through, install-update, and re-engagement limits from the current documentation and the reference; do not merge the two concepts.
Lock the postback to finalize a conversion value before the window ends and receive the postback sooner:
After locking, the system ignores further updates in that conversion window.
Disclosure grows with the system-assigned data tier. Code and analytics must tolerate absent source digits, fine/coarse conversion values, publisher item ID, and country. The reference owns the detailed tier matrix.
Fine values are integers from 0...63 (6 bits). They are available only in the first postback and only at Tier 2 or higher:
Three levels for lower tiers and second/third postbacks:
Separate conversion values for install vs. re-engagement postbacks. In server
JSON, use "conversion-type": "re-engagement" with the hyphen; Swift APIs use
.reengagement without it.
Use conversion tags to selectively update specific postbacks when overlapping conversion windows exist:
The system delivers the conversion tag through the re-engagement URL's
AdAttributionKitReengagementOpen query parameter.
Re-engagement tracks users who already have the advertised app installed and interact with an ad to return to it.
Set eligible-for-re-engagement to true in the JWS payload when generating
the impression.
Pass a universal link that the system opens in the advertised app:
The system appends AdAttributionKitReengagementOpen as a query parameter. The
advertised app checks for this parameter to detect AdAttributionKit-driven
opens:
AdAttributionKitReengagementOpen parameter is always present on the
URL, even when the system does not create a postback.| Mistake | Fix |
|---|---|
| First launch never updates conversion value | Call the canonical first-launch update before the intended window elapses. |
| Ad network ID contains uppercase characters | Use the exact lowercase network identifier. |
handleTap() uses a stale impression or lacks the current attribution view tap | Cover the ad with UIEventAttributionView, keep the impression fresh, and call from the validated tap flow. |
| Tap errors are discarded | Handle expired-impression and missing-view cases explicitly. |
| Postback endpoint delays or drops the response | Accept, persist/queue processing, and return the expected success promptly. |
AdNetworkIdentifiers
(lowercase)kidUIEventAttributionView overlays each tappable click-through ad/controlAppImpression is no older than 15 minutes at handleTap()updateConversionValue on first launchpostback-identifierAppImpression.isSupported checked before attempting impression APIs