Skip to content

feat(audience-sdk): iOS Info.plist post-processor for ATT + SKAdNetwork (SDK-308)#744

Merged
nattb8 merged 1 commit intomainfrom
feat/sdk-308-ios-info-plist-post-processor
May 7, 2026
Merged

feat(audience-sdk): iOS Info.plist post-processor for ATT + SKAdNetwork (SDK-308)#744
nattb8 merged 1 commit intomainfrom
feat/sdk-308-ios-info-plist-post-processor

Conversation

@nattb8
Copy link
Copy Markdown
Collaborator

@nattb8 nattb8 commented May 6, 2026

Summary

  • Adds an iOS [PostProcessBuild] that injects NSUserTrackingUsageDescription and SKAdNetworkItems into the generated Xcode project's Info.plist.
  • Build-time settings live on a new AudienceMobileBuildSettings ScriptableObject (created via Assets → Create → Immutable Audience → Mobile Build Settings). The runtime AudienceConfig object cannot be read at build time, so build-only values need an asset-backed source.
  • Both keys are gated by the AUDIENCE_MOBILE_ATTRIBUTION scripting define on the iOS player target — without the define, Info.plist is left untouched (Apple flags apps that include either key without the corresponding code paths).
  • Tools → Immutable → Audience → Validate iOS Build Settings previews what would be injected without running a full build.

Behaviour notes baked in: callbackOrder 9050 (above Unity's defaults; ad-network SDKs with higher orders can extend our SKAdNetworkItems); merging with any pre-existing SKAdNetworkItems array; case-insensitive dedupe per Apple's spec; default NSUserTrackingUsageDescription fallback so a build never ships with the key missing.

Why these two keys?

iOS attribution on post-ATT devices (iOS 14.5+) works through two complementary mechanisms, and both require Info.plist entries before the binary is signed.

NSUserTrackingUsageDescription is the text Apple shows in the system App Tracking Transparency dialog. It is required whenever the app calls ATTrackingManager.requestTrackingAuthorization. If the key is absent when that call is made, iOS crashes the app. When the user grants permission, ad networks gain access to the IDFA (Identifier for Advertisers), which enables full cross-app attribution.

SKAdNetworkItems covers the case where the user denies ATT, or where IDFA is otherwise unavailable. Apple's SKAdNetwork framework can report a conversion (ad click → game install) back to an ad network without identifying the individual user. For a network's conversions to be credited, its registered identifier must appear in this list. Any network missing from the list cannot attribute installs from their campaigns at all.

Together, the two keys mean the Audience SDK can measure player acquisition accurately regardless of whether a given user has granted tracking consent. The post-processor automates what would otherwise be a manual Info.plist edit each time a studio adds or changes ad network partners.

Test plan

  • 10/10 EditMode unit tests pass against real UnityEditor.iOS.Xcode.PlistDocument (cover: defaults, custom copy, overwrite, merge, dedupe, null/whitespace skip, no-asset path).
  • Real iOS IL2CPP build verified locally — generated Info.plist contains the configured SKAdNetworkIdentifier and the custom NSUserTrackingUsageDescription from the settings asset.

🤖 Generated with Claude Code


Note

Medium Risk
Touches iOS build post-processing and Info.plist generation, which can cause App Store submission/runtime issues if misconfigured, though it is gated behind a scripting define and covered by unit tests.

Overview
Adds an iOS [PostProcessBuild] step (iOSInfoPlistPostProcessor) that, when AUDIENCE_MOBILE_ATTRIBUTION is enabled, writes NSUserTrackingUsageDescription and merges/dedupes SKAdNetworkItems into the generated Xcode Info.plist.

Introduces an editor-only AudienceMobileBuildSettings ScriptableObject (with menu item creation + asset discovery) to supply ATT prompt copy and SKAdNetwork IDs at build time, plus a validation menu command to preview what will be injected.

Adds an editor test assembly and unit tests for the plist mutation helpers; exposes editor internals to tests via InternalsVisibleTo.

Reviewed by Cursor Bugbot for commit a56fea7. Bugbot is set up for automated code reviews on this repo. Configure here.

@nattb8 nattb8 requested review from a team as code owners May 6, 2026 23:15
@nattb8 nattb8 force-pushed the feat/sdk-308-ios-info-plist-post-processor branch from be395ca to 6d30455 Compare May 6, 2026 23:21
…rk (SDK-308)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@nattb8 nattb8 force-pushed the feat/sdk-308-ios-info-plist-post-processor branch from 6d30455 to a56fea7 Compare May 7, 2026 00:39
@nattb8 nattb8 enabled auto-merge May 7, 2026 03:20
@nattb8 nattb8 merged commit d8e56f0 into main May 7, 2026
58 of 59 checks passed
@nattb8 nattb8 deleted the feat/sdk-308-ios-info-plist-post-processor branch May 7, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants