iOS SDK - 广告收入追踪

广告收入归因

追踪来自聚合平台的广告收入,并将其归因到获取用户的营销活动,从而提供涵盖 活动成本、应用内购买和广告变现的完整 ROI 可见性。

概述

什么是广告收入归因

广告收入归因将移动应用广告收入与推动应用安装的用户获取活动相连接, 使您能够衡量包含广告变现在内的真实活动盈利能力。

主要优势:

  • 统一的 ROI 视图: 在单一控制台中查看活动成本、应用内收入 和广告收入
  • 活动优化: 将广告收入数据回传给广告网络,以改进 竞价和定向
  • LTV 衡量: 计算包含广告变现在内的用户完整生命周期价值

数据来源: 广告收入数据通常来自您的聚合平台(例如 AdMob、AppLovin MAX、IronSource), 以用户级别或展示级别提供。Singular 支持多种集成方式来接收此数据。

了解更多: 有关设置、报告和故障排除的完整详情,请参阅 广告收入归因常见问题


实施要求

关键准则

必填的 SingularAdData 参数: 构造函数参数 adPlatformwithCurrencywithRevenue 均为必填项。如果任一项缺失、为空或无效(依据 -hasRequiredParams 判定), SDK 会静默丢弃对 +adRevenue: 的调用,且不会抛出异常。在 SDK 未启动时,该调用也会静默无效,因此在调用前请始终确认 +start: 已运行。

使用正确的构造函数签名: -initWithAdPlatform:withCurrency:withRevenue: 是受支持的构造函数。旧版的 -initWithAdPlatfrom: (注意拼写错误)被标注为 __attribute__((deprecated)) ,会产生编译器警告。请勿在新代码中使用。

数据精度至关重要:

  1. 货币代码: 使用三位字母的 ISO 4217 货币代码 (例如 USD、EUR、INR)。许多聚合平台以 USD 报告, 请在实施前验证您平台的货币
  2. 发送前验证: 在调用 Singular.adRevenue() 之前,请始终验证收入和货币数据。 错误的数据提交后无法更正
  3. 平台差异: 与使用 micros 的 Android 不同,iOS 直接以标准货币单位 (例如 $0.005)接收收入。请始终查看您平台的文档以确定正确的格式

设置步骤

请按照以下步骤实施广告收入归因:

  1. 更新 SDK: 确保您使用的是最新版本的 Singular SDK
  2. 选择集成方式: 选择下方与您的设置相匹配的聚合平台集成
  3. 实现回调: 添加平台特定的 paid 事件监听器以捕获收入数据
  4. 验证数据: 测试收入报告,并验证数据已显示在 Singular 控制台中

平台集成

AdMob 集成

使用 paid 事件监听器追踪来自 Google AdMob 的广告收入,以实现展示级别的 收入报告。

要求:

  • 在您的 AdMob 账户中启用 paid 事件追踪(参见 AdMob 支持
  • 为 iOS 实现 Google Mobile Ads SDK(参见 入门指南

平台收入报告: AdMob 在不同平台上以不同方式报告收入。iOS 以标准货币单位 返回收入(例如 $0.005 = 0.005)。请将该值直接发送给 Singular,无需转换。

实现

在加载广告时设置 paid 事件处理程序,以捕获收入数据并将其发送给 Singular。

Swift Objective-C
import Singular
import GoogleMobileAds

private let adUnitID = "AD_UNIT_ID"
var rewardedAd: GADRewardedAd?

func loadRewardedAd() {
    let request = GADRequest()

    GADRewardedAd.load(withAdUnitID: adUnitID, request: request) { [weak self] ad, error in
        guard let self = self else { return }

        if let error = error {
            print("Rewarded ad failed to load: \(error.localizedDescription)")
            return
        }

        self.rewardedAd = ad

        // Set paid event handler for revenue tracking
        self.rewardedAd?.paidEventHandler = { adValue in
            // Extract revenue and currency from AdValue
            let revenue = adValue.value.doubleValue
            let currency = adValue.currencyCode

            // Validate revenue and currency before sending
            guard revenue > 0, let currency = currency, !currency.isEmpty else {
                print("Invalid ad revenue data: revenue = \(revenue), currency = \(String(describing: currency))")
                return
            }

            // Create ad revenue data object
            let data = SingularAdData(
                adPlatform: "AdMob",
                currency: currency,
                revenue: revenue
            )

            // Send to Singular
            Singular.adRevenue(data)
            print("Ad revenue sent: \(revenue) \(currency)")
        }
    }
}

AppLovin MAX 集成

使用 AppLovin 的 Impression-Level User Revenue API 分享展示级别的广告收入。

要求:

实现

通过 AppLovin Communicator 回调处理收入消息。

Swift Objective-C
import Singular
import AppLovinSDK

func didReceive(_ message: ALCMessage) {
    // Check for revenue events topic
    if message.topic == "max_revenue_events" {
        // Extract and validate revenue value
        guard let revenueValue = message.data["revenue"] as? Double,
              revenueValue > 0 else {
            print("Failed to parse valid revenue value or revenue is not greater than 0")
            return
        }

        // Create ad revenue data object
        let data = SingularAdData(
            adPlatform: "AppLovin",
            currency: "USD",  // AppLovin typically reports in USD
            revenue: revenueValue
        )

        // Send to Singular
        Singular.adRevenue(data)
        print("Ad revenue sent: \(revenueValue) USD")
    }
}

Unity LevelPlay (IronSource) 集成

使用 IronSource SDK 追踪来自 ironSource 和聚合网络的展示级别收入。

要求:

  • 实现 ironSource SDK(参见 入门指南
  • 在您的 IronSource 控制台中启用 ARM SDK Postbacks 标志
  • 设置 impression data 监听器以接收收入回调

了解更多: 有关完整的设置详情,请参阅 IronSource 广告收入文档

实现

实现 impression data success 回调以捕获并发送收入。

Swift Objective-C
import Singular
import IronSource

func impressionDataDidSucceed(_ impressionData: ISImpressionData?) {
    // Validate impression data
    guard let impressionData = impressionData else {
        print("No impression data available")
        return
    }

    // Extract and validate revenue
    let revenue = impressionData.revenue
    guard revenue > 0 else {
        print("Invalid revenue value: \(revenue)")
        return
    }

    // Create ad revenue data object
    let data = SingularAdData(
        adPlatform: "IronSource",
        currency: "USD",  // IronSource typically reports in USD
        revenue: revenue
    )

    // Send to Singular
    Singular.adRevenue(data)
    print("Ad revenue sent: \(revenue) USD")
}

TradPlus 集成

使用 impression delegate 捕获来自 TradPlus 聚合的广告收入。

要求:

  • 通过 TradPlus.sharedInstance().impressionDelegate 设置 impression delegate
  • 处理 tradPlusAdImpression 回调以接收收入数据
  • 将 eCPM 从毫单位转换为标准货币单位(除以 1000)

实现

注册一个 impression delegate 以追踪所有广告展示和收入。

Swift Objective-C
import Singular
import TradPlusSDK

// Set up the delegate
TradPlus.sharedInstance().impressionDelegate = self

// Delegate method for handling ad impressions
func tradPlusAdImpression(_ adInfo: [String: Any]) {
    let currency = "USD"

    // Extract and validate eCPM value
    guard let ecpmValue = adInfo["ecpm"] as? NSNumber else {
        print("No eCPM data available in adInfo")
        return
    }

    // Convert eCPM from milli-units to dollars
    let revenue = ecpmValue.doubleValue / 1000.0

    // Validate revenue
    guard revenue > 0 else {
        print("Ad Revenue value out of expected range: \(revenue)")
        return
    }

    // Create ad revenue data object
    let data = SingularAdData(
        adPlatform: "TradPlus",
        currency: currency,
        revenue: revenue
    )

    // Send to Singular
    Singular.adRevenue(data)
    print("Ad revenue sent: \(revenue) \(currency)")
}

通用集成(其他平台)

使用通用的 SingularAdData 接口集成任何聚合平台。

要求:

  • 可以访问聚合平台的展示级别收入数据
  • 标准货币单位的收入金额
  • ISO 4217 货币代码(例如 USD、EUR、INR)

数据精度: 在发送给 Singular 之前,请验证收入和货币数据。 错误的数据提交后无法更正。

实现

使用平台名称、货币和收入创建 SingularAdData 对象,然后调用 Singular.adRevenue()

Swift Objective-C
import Singular

func reportAdRevenue(adPlatform: String, currency: String, revenue: Double) {
    // Validate revenue
    guard revenue > 0 else {
        print("Invalid revenue value: \(revenue)")
        return
    }

    // Validate currency
    guard !currency.isEmpty else {
        print("Invalid currency: \(currency)")
        return
    }

    // Create ad revenue data object
    let data = SingularAdData(
        adPlatform: adPlatform,
        currency: currency,
        revenue: revenue
    )

    // Send to Singular
    Singular.adRevenue(data)
    print("Revenue sent: \(revenue) \(currency) from \(adPlatform)")
}

// Example usage
reportAdRevenue(adPlatform: "MyMediationPlatform", currency: "USD", revenue: 0.05)

使用其他归因丰富广告数据

SingularAdData 公开了用于展示级别Meta数据的 setter 方法。当您的聚合平台提供这些信息时, 使用它们以放置位置、广告单Meta、聚合分组和精度细节来丰富事件。

与 Android SDK 不同, SingularAdData 的 setter 返回 void ,且不可链式调用。请将每个 setter 单独写在一行。

方法 描述
setNetworkName: 覆盖网络名称(默认为传递给构造函数的广告平台)。在聚合中, 当底层网络与聚合平台不同时使用。
setAdType: 广告形式(例如 @"Rewarded"@"Interstitial"@"Banner")。
setGroupType: 您的聚合平台定义的广告组分类。
setImpressionId: 展示的唯一标识符,用于去重和对账。
setAdPlacementName: 人类可读的放置位置名称(例如 @"level_complete")。
setAdUnitId: 平台特定的广告单Meta标识符(例如 AdMob 的 @"ca-app-pub-..." )。
setAdUnitName: 人类可读的广告单Meta名称。
setAdGroupId: 来自聚合平台的广告组标识符。
setAdGroupName: 人类可读的广告组名称。
setAdGroupPriority: 在聚合 waterfall 中分配给广告组的优先级。
setPrecision: 平台支持时的收入精度指示符(例如 @"publisher_provided"@"estimated"@"exact")。
setPlacementId: 平台特定的放置位置标识符。
setLimitDataSharing: 为这个单一广告事件覆盖全局数据共享限制, 例如用户已选择退出个性化广告时。

Swift 示例:

let data = SingularAdData(adPlatform: "AdMob",
                          withCurrency: "USD",
                          withRevenue: NSNumber(value: 0.05))
data.setAdUnitId("ca-app-pub-123456789/1234567890")
data.setAdType("Rewarded")
data.setAdPlacementName("level_complete")
data.setImpressionId("imp_abc123")
data.setPrecision("publisher_provided")

Singular.adRevenue(data)

Objective-C 示例:

SingularAdData *data = [[SingularAdData alloc]
    initWithAdPlatform:@"AdMob"
          withCurrency:@"USD"
           withRevenue:@(0.05)];
[data setAdUnitId:@"ca-app-pub-123456789/1234567890"];
[data setAdType:@"Rewarded"];
[data setAdPlacementName:@"level_complete"];
[data setImpressionId:@"imp_abc123"];
[data setPrecision:@"publisher_provided"];

[Singular adRevenue:data];

测试和验证

验证收入报告

测试您的广告收入实现,确保数据正确传输到 Singular。

  1. 检查日志: 验证收入回调日志显示正确的值和货币
  2. 测试广告: 加载并展示测试广告以触发收入事件
  3. 控制台验证: 确认收入在 24 小时内显示在 Singular 控制台中
  4. 数据精度: 验证收入金额与您的聚合平台报告相匹配

故障排除: 如果收入未显示在 Singular 中,请检查:

  • 广告收入归因已在您的 Singular 账户中启用
  • 收入值大于 0
  • 货币代码是有效的 ISO 4217 代码
  • 平台名称与 Singular 的预期格式相匹配