Unity SDK - 支持 SKAdNetwork 和 ATT

文件

支持 SKAdNetwork

SKAdNetwork 是苹果公司为 iOS 应用程序安装活动提供的注重隐私的归因框架。从 Unity SDK 4.0.17 版开始,SKAdNetwork 默认在托管模式下启用,Singular 会根据您在仪表板中配置的转换模型自动更新转换值。

无需额外配置:如果您使用的是最新的 Unity SDK,SKAdNetwork 开箱即用。 基本功能无需更改代码或进行额外设置。

了解 SKAN 模式

托管模式(默认)

在托管模式下,Singular 会根据您在仪表板中配置的转换模型自动处理转换值更新。这是大多数应用程序的推荐方法,因为它只需最少的代码,并提供最佳的转换跟踪。

  • 自动更新:Singular 根据用户事件和配置的模型管理所有转换值更新。
  • 仪表板配置:在 Singular 面板中设计转换模型,无需修改代码。
  • 优化:受益于 Singular 在苹果限制条件下最大化转换值更新的专业知识。

手动模式(高级)

手动模式可让您完全控制转换值更新,允许您实施自定义逻辑来确定何时以及如何更新 SKAN 转换值。只有当您有管理模式无法满足的特殊要求时,才使用该模式。

高级功能:手动模式需要仔细实施并了解 Apple 的 SKAdNetwork 限制,包括转换值更新窗口和限制。大多数应用程序应使用托管模式。

旧版 SDK 版本

如果您使用的 Unity SDK 版本早于 4.0.17,则需要使用以下方法之一手动启用 SKAdNetwork 支持。

在旧版 SDK 中启用 SKAdNetwork
#

方法 1:Unity 检查器配置

  1. 在 Unity 场景层次结构中选择SingularSDKObject
  2. 在 "检查器 "窗格中,找到SKANEnabled属性。
  3. SKANEnabled设置为True
  4. 保存场景并重建项目。

方法 2:程序化注册

在跟踪任何事件之前,在应用程序初始化代码中调用注册方法。

C#
using UnityEngine;
using Singular;

public class AppInitializer : MonoBehaviour
{
    void Awake()
    {
        // Register for SKAdNetwork attribution
        SingularSDK.SkanRegisterAppForAdNetworkAttribution();
    }
}

建议升级到最新的 Unity SDK 版本,以便从自动启用 SKAdNetwork 以及最新功能和错误修复中获益。

配置手动模式

要实施自定义转换值逻辑,请启用 "手动模式 "并使用提供的 SDK 方法在应用程序的整个生命周期中更新和监控转换值。

在手动模式下使用 SKAdNetwork(高级)
#

启用手动模式

  1. 在 Unity 场景层次结构中选择SingularSDKObject
  2. 在 "检查器 "窗格中,找到manualSKANConversionManagement属性。
  3. manualSKANConversionManagement设置为True

更新转换值

使用此方法可根据自定义逻辑手动更新 SKAdNetwork 转换值。转换值必须是 0 到 63 之间的整数。

重要信息:此方法仅在manualSKANConversionManagement 设置为 True 时有效。 如果托管模式处于活动状态,手动更新将被忽略。

签名

C#
public static bool SkanUpdateConversionValue(int value)

使用示例

C#
using UnityEngine;
using Singular;

public class ConversionTracker : MonoBehaviour
{
    void OnUserSignUp()
    {
        // Track the sign-up event
        SingularSDK.Event("SignUp");

        // Update SKAN conversion value to 7
        bool success = SingularSDK.SkanUpdateConversionValue(7);

        if (success)
        {
            Debug.Log("Conversion value updated successfully");
        }
        else
        {
            Debug.LogWarning("Failed to update conversion value");
        }
    }

    void OnPurchaseComplete(float purchaseAmount)
    {
        // Track revenue event
        SingularSDK.Revenue("USD", purchaseAmount);

        // Update conversion value based on purchase tier
        int conversionValue = CalculateConversionValue(purchaseAmount);
        SingularSDK.SkanUpdateConversionValue(conversionValue);
    }

    int CalculateConversionValue(float amount)
    {
        // Your custom logic to determine conversion value
        if (amount >= 100) return 63;      // High value
        if (amount >= 50) return 40;       // Medium value
        if (amount >= 10) return 20;       // Low value
        return 10;                          // Minimal value
    }
}

获取当前转换值

读取 Singular SDK 追踪的当前转换值。这对于根据当前状态执行条件逻辑非常有用。

签名

C#
public static int? SkanGetConversionValue()

使用示例

C#
using UnityEngine;
using Singular;

public class ConversionMonitor : MonoBehaviour
{
    void CheckConversionValue()
    {
        int? currentValue = SingularSDK.SkanGetConversionValue();

        if (currentValue.HasValue)
        {
            Debug.Log($"Current conversion value: {currentValue.Value}");

            // Only update if current value is below threshold
            if (currentValue.Value < 30)
            {
                SingularSDK.SkanUpdateConversionValue(30);
            }
        }
        else
        {
            Debug.LogWarning("Conversion value not available");
        }
    }
}

监控转换值更新

设置一个处理程序,以便在转换值发生变化时接收实时通知。这样,您就能对转换值更新做出反应,并记录分析结果或触发其他应用程序行为。

签名

C#
public static void SetConversionValueUpdatedHandler(SingularConversionValueUpdatedHandler handler)

使用示例

C#
using UnityEngine;
using Singular;

public class ConversionValueMonitor : MonoBehaviour, SingularConversionValueUpdatedHandler
{
    void Awake()
    {
        // Register this class as the conversion value update handler
        SingularSDK.SetConversionValueUpdatedHandler(this);
    }

    // This method is called whenever the conversion value is updated
    public void OnConversionValueUpdated(int newValue)
    {
        Debug.Log($"Conversion value updated to: {newValue}");

        // Log the update to your analytics
        LogConversionValueUpdate(newValue);

        // Trigger any app-specific behavior
        if (newValue >= 50)
        {
            UnlockPremiumFeature();
        }
    }

    void LogConversionValueUpdate(int value)
    {
        // Your analytics logging logic
        Debug.Log($"Analytics: SKAN CV = {value}");
    }

    void UnlockPremiumFeature()
    {
        // Your custom logic
        Debug.Log("Premium feature unlocked based on high conversion value");
    }
}

最佳实践:使用转换值处理程序在整个应用程序中保持当前转换状态的同步视图。这对于调试和确保自定义逻辑正常工作特别有用。


支持应用程序跟踪透明度 (ATT)

App Tracking Transparency (ATT) 是 Apple 的隐私框架,要求在访问设备的 IDFA(广告商识别码)和共享用户数据前征得用户同意。正确实施 ATT 对于 iOS 归因和最大限度地提高用户获取活动的准确性至关重要。

ATT 为何对归因至关重要

从 iOS 14.5 开始,应用程序在访问 IDFA 之前必须通过 ATT 框架请求用户许可。虽然在没有 IDFA 的情况下仍可使用指纹识别和概率方法进行归因,但有了 IDFA,归因的准确性会大大提高,并提供确定性匹配。

  • 确定性归属:IDFA 可实现精确的设备级归因,将广告印象与安装直接联系起来。
  • 广告网络优化:通过访问 IDFA,广告网络可以更好地优化广告活动并提供更准确的报告。
  • 用户级洞察:访问 IDFA 可以进行更精细的用户行为分析和群组跟踪。

建议:Singular 强烈建议实施 ATT 提示并征求用户同意。 向用户解释其好处(个性化广告、更好的应用体验),以最大限度地提高选择加入率。

SDK 初始化时机

相对于 ATT 提示,SDK 初始化的时机至关重要。 如果 SDK 在用户响应 ATT 提示之前初始化并发送第一个会话,则无法捕获 IDFA,导致归因不够准确。

为什么要延迟初始化?

默认情况下,Singular SDK 会在初始化后立即发送会话。 当会话来自新设备时,Singular 会仅使用当时可用的数据触发归因过程。如果用户尚未回复 ATT 提示,IDFA 将不可用,归因将基于不太准确的方法。

关键:请务必Singular SDK 发送第一个会话之前请求 ATT 同意并检索 IDFA。否则将永久丢失该设备归因数据的 IDFA。

配置 SDK 等待超时

通过设置waitForTrackingAuthorizationWithTimeoutInterval 属性配置 SDK,使其在初始化前等待用户的 ATT 响应。该延迟可为用户提供响应 ATT 提示的时间,同时防止在未显示提示时出现无限期延迟。

配置步骤

  1. 在 Unity 场景层次结构中选择SingularSDKObject
  2. 在 "检查器 "窗格中,找到waitForTrackingAuthorizationWithTimeoutInterval属性。
  3. 根据 ATT 实现设置该值:
    • 显示 ATT 提示:设置为300(5 分钟
    • 不显示 ATT 提示:保持为0(不等待

建议值:如果您的应用程序显示 ATT 提示,请将超时设置为 300 秒(5 分钟)。 这将为用户提供足够的时间查看和回复提示,而不会因提示延迟或不显示而造成不良的用户体验。

实施示例

下面介绍如何在您的 Unity 应用程序中使用正确的 SDK 初始化计时来实现 ATT。

C#
using UnityEngine;
using Singular;

#if UNITY_IOS
using Unity.Advertisement.IosSupport;
#endif

public class ATTManager : MonoBehaviour
{
    void Start()
    {
#if UNITY_IOS
        // Check ATT status on iOS
        RequestTrackingAuthorization();
#else
        // Initialize SDK immediately on non-iOS platforms
        InitializeSingularSDK();
#endif
    }

#if UNITY_IOS
    void RequestTrackingAuthorization()
    {
        // Check current authorization status
        var status = ATTrackingStatusBinding.GetAuthorizationTrackingStatus();

        if (status == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED)
        {
            // Request authorization if not yet determined
            ATTrackingStatusBinding.RequestAuthorizationTracking(OnATTResponse);
        }
        else
        {
            // Status already determined, initialize SDK
            InitializeSingularSDK();
        }
    }

    void OnATTResponse(int status)
    {
        // Log the user's response
        switch (status)
        {
            case (int)ATTrackingStatusBinding.AuthorizationTrackingStatus.AUTHORIZED:
                Debug.Log("User authorized tracking - IDFA will be available");
                break;
            case (int)ATTrackingStatusBinding.AuthorizationTrackingStatus.DENIED:
                Debug.Log("User denied tracking - IDFA not available");
                break;
            case (int)ATTrackingStatusBinding.AuthorizationTrackingStatus.RESTRICTED:
                Debug.Log("Tracking restricted by device settings");
                break;
            default:
                Debug.Log("ATT status unknown");
                break;
        }

        // Initialize SDK after receiving response
        InitializeSingularSDK();
    }
#endif

    void InitializeSingularSDK()
    {
        // SDK is initialized with waitForTrackingAuthorizationWithTimeoutInterval
        // configured in the Inspector, so it will wait for ATT if needed
        // If Initialize On Awake is disabled, manually initialize here
        // SingularSDK.InitializeSingularSDK();

        Debug.Log("Singular SDK initialized");
    }
}

ATT 最佳实践

  • 预提示信息:向用户显示 ATT 前屏幕,解释为什么需要跟踪权限,以及这样做对用户有什么好处(更好的广告、更好的体验)。这可以大大提高选择加入率。
  • 时机很重要:在应用程序流程的自然时刻显示 ATT 提示,而不是在首次启动时立即显示。 让用户先体验您的应用。
  • 自定义消息:使用NSUserTrackingUsageDescription 键在 Info.plist 文件中自定义 ATT 提示信息,以清楚地解释您的跟踪目的。
  • 彻底测试:测试授权和拒绝两种情况,确保无论用户如何选择,您的应用都能正常运行。
  • 尊重用户的选择:切勿反复提示已拒绝跟踪的用户,也不要显示激进的信息,迫使他们选择加入。

应用商店审查:未正确实施 ATT 或试图规避框架的应用程序可能会在 App Store 审核期间被拒绝。确保您的实施遵循 Apple 的指导原则并尊重用户的隐私选择。

其他资源