diff --git a/src/Packages/Audience/Runtime/AudienceConfig.cs b/src/Packages/Audience/Runtime/AudienceConfig.cs index c2681509..d0dd7090 100644 --- a/src/Packages/Audience/Runtime/AudienceConfig.cs +++ b/src/Packages/Audience/Runtime/AudienceConfig.cs @@ -49,6 +49,40 @@ public class AudienceConfig /// public bool Debug { get; set; } = false; + /// + /// Opts into mobile install-attribution signals (iOS ATT / IDFA / + /// SKAdNetwork, Android Advertising ID / Install Referrer). Default + /// false. + /// + /// + /// Two gates control attribution; both must be set for any data to + /// ship: + /// + /// 1. Build-time: add AUDIENCE_MOBILE_ATTRIBUTION to Player + /// Settings → Other Settings → Scripting Define Symbols. Controls + /// the AD_ID Android manifest permission, the iOS Privacy Manifest + /// variant (NSPrivacyTracking), and whether native + /// attribution code is compiled into the binary. + /// + /// 2. Runtime: this flag. Controls whether attribution data is + /// collected at runtime. Without the define, this setter is a + /// no-op. + /// + /// Studios who set neither ship a clean binary — no AD_ID permission, + /// no native attribution code, NSPrivacyTracking = false. + /// + public bool EnableMobileAttribution { get; set; } = false; + + /// + /// SKAdNetwork IDs the iOS post-processor injects into Info.plist + /// at build time. Ignored on Android. + /// + /// + /// Read only when and the + /// AUDIENCE_MOBILE_ATTRIBUTION scripting define are both set. + /// + public string[]? SKAdNetworkIds { get; set; } + /// /// Interval between automatic flushes to the backend, in seconds. /// diff --git a/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs b/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs new file mode 100644 index 00000000..84a198a1 --- /dev/null +++ b/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs @@ -0,0 +1,41 @@ +#nullable enable + +using NUnit.Framework; + +namespace Immutable.Audience.Tests +{ + [TestFixture] + internal class AudienceConfigTests + { + [Test] + public void EnableMobileAttribution_DefaultsToFalse() + { + // Default-off matters: a studio that never opts in must ship a + // clean binary, no AD_ID permission, NSPrivacyTracking false. + var config = new AudienceConfig(); + Assert.IsFalse(config.EnableMobileAttribution); + } + + [Test] + public void SKAdNetworkIds_DefaultsToNull() + { + var config = new AudienceConfig(); + Assert.IsNull(config.SKAdNetworkIds); + } + + [Test] + public void EnableMobileAttribution_RoundTrips() + { + var config = new AudienceConfig { EnableMobileAttribution = true }; + Assert.IsTrue(config.EnableMobileAttribution); + } + + [Test] + public void SKAdNetworkIds_RoundTrips() + { + var ids = new[] { "abc123.skadnetwork", "def456.skadnetwork" }; + var config = new AudienceConfig { SKAdNetworkIds = ids }; + Assert.AreSame(ids, config.SKAdNetworkIds); + } + } +} diff --git a/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs.meta b/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs.meta new file mode 100644 index 00000000..ea8a7382 --- /dev/null +++ b/src/Packages/Audience/Tests/Runtime/AudienceConfigTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7a0b1d2e3f4a5b6c7d8e9f0a1b2c3d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: