広告収益アトリビューション
メディエーションプラットフォームからの広告収益をトラッキングし、ユーザーを 獲得したマーケティングキャンペーンに帰属させることで、キャンペーンコスト、 アプリ内購入、広告マネタイゼーション全体にわたる完全なROIの可視性を提供します。
概要
広告収益アトリビューションとは
広告収益アトリビューションは、モバイルアプリの広告収益をアプリインストールを 促進したユーザー獲得キャンペーンと結びつけ、広告マネタイゼーションを含む真の キャンペーン収益性を測定できるようにします。
主なメリット:
- 統合ROIビュー: キャンペーンコスト、アプリ内収益、広告収益を 1つのダッシュボードで確認
- キャンペーンの最適化: 広告収益データを広告ネットワークへ 送り返し、入札とターゲティングを改善
- LTV測定: 広告マネタイゼーションを含む完全なユーザー ライフタイムバリューの算出
データソース: 広告収益データは通常、メディエーションプラットフォーム (例: AdMob、AppLovin MAX、IronSource) からユーザー単位またはインプレッション 単位で提供されます。Singularはこのデータを受信するための複数の統合方法をサポートしています。
詳細を見る: セットアップ、レポート、トラブルシューティングに関する詳細は、 広告収益アトリビューションFAQ を参照してください。
実装要件
重要なガイドライン
必須のSingularAdDataパラメータ:
コンストラクタ引数
adPlatform、
withCurrency、
withRevenue
はすべて必須です。いずれかが欠落、空、または無効な場合
(-hasRequiredParams による判定)、
SDKは例外を発生させずに
+adRevenue:
の呼び出しを暗黙的に破棄します。SDKが開始されていない状態でも呼び出しは
暗黙的にno-opとなるため、呼び出しの前に必ず
+start:
が実行されていることを確認してください。
正しいコンストラクタシグネチャを使用:
-initWithAdPlatform:withCurrency:withRevenue:
がサポートされているコンストラクタです。レガシーの
-initWithAdPlatfrom:
(スペルミスに注意)は
__attribute__((deprecated))
とアノテートされており、コンパイラ警告を発生させます。新しいコードでは使用しないでください。
データの正確性が極めて重要:
- 通貨コード: 3文字のISO 4217通貨コードを使用してください (例: USD、EUR、INR)。多くのメディエーションプラットフォームはUSDで レポートするため、実装前にプラットフォームの通貨を検証してください
-
送信前の検証:
Singular.adRevenue()を呼び出す前に、必ず収益と通貨データを検証してください。 誤ったデータは送信後に修正できません - プラットフォームの違い: iOSはmicrosを使用するAndroidとは異なり、 標準通貨単位 (例: $0.005) で収益を直接受信します。正しい形式については、 常にプラットフォームのドキュメントを確認してください
セットアップ手順
広告収益アトリビューションを実装するには、以下の手順に従ってください:
- SDKの更新: 最新のSingular SDKバージョンを使用していることを 確認
- 統合方法の選択: セットアップに適した以下のメディエーション プラットフォーム統合を選択
- コールバックの実装: 収益データをキャプチャするための プラットフォーム固有のpaidイベントリスナーを追加
- データの検証: 収益レポートをテストし、Singularダッシュボードに データが表示されることを確認
プラットフォーム統合
AdMob統合
インプレッション単位の収益レポートのために、paidイベントリスナーを使用して Google AdMobからの広告収益をトラッキングします。
要件:
- AdMobアカウントでpaidイベントトラッキングを有効化してください ( AdMobサポート を参照)
- iOS用のGoogle Mobile Ads SDKを実装してください ( スタートガイド を参照)
プラットフォーム収益レポート: AdMobはプラットフォームによって 収益のレポート方法が異なります。iOSは標準通貨単位 (例: $0.005 = 0.005) で収益を返します。値を変換せずそのままSingularに送信してください。
実装
広告のロード時にpaidイベントハンドラを設定して収益データをキャプチャし、 Singularに送信します。
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)")
}
}
}
#import <Singular/Singular.h>
#import <GoogleMobileAds/GoogleMobileAds.h>
static NSString *const adUnitID = @"AD_UNIT_ID";
@interface AdManager ()
@property(nonatomic, strong) GADRewardedAd *rewardedAd;
@end
@implementation AdManager
- (void)loadRewardedAd {
GADRequest *request = [[GADRequest alloc] init];
[GADRewardedAd loadWithAdUnitID:adUnitID
request:request
completionHandler:^(GADRewardedAd *ad, NSError *error) {
if (error) {
NSLog(@"Rewarded ad failed to load: %@", error.localizedDescription);
return;
}
self.rewardedAd = ad;
// Set paid event handler for revenue tracking
self.rewardedAd.paidEventHandler = ^(GADAdValue *adValue) {
// Extract revenue and currency from AdValue
double revenue = adValue.value.doubleValue;
NSString *currency = adValue.currencyCode;
// Validate revenue and currency before sending
if (revenue > 0 && currency.length > 0) {
// Create ad revenue data object
SingularAdData *data = [[SingularAdData alloc]
initWithAdPlatform:@"AdMob"
currency:currency
revenue:revenue];
// Send to Singular
[Singular adRevenue:data];
NSLog(@"Ad revenue sent: %f %@", revenue, currency);
} else {
NSLog(@"Invalid ad revenue data: revenue = %f, currency = %@",
revenue, currency);
}
};
}];
}
@end
AppLovin MAX統合
AppLovinのImpression-Level User Revenue APIを使用して、インプレッション単位の 広告収益を共有します。
要件:
- AppLovin MAX SDKを実装してください ( Impression-Level Revenue APIガイド を参照)
-
AppLovin Communicator経由で
max_revenue_eventsトピックをサブスクライブしてください
実装
AppLovin Communicatorのコールバックを通じて収益メッセージを処理します。
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")
}
}
#import <Singular/Singular.h>
#import <AppLovinSDK/AppLovinSDK.h>
- (void)didReceive:(ALCMessage *)message {
// Check for revenue events topic
if ([@"max_revenue_events" isEqualToString:message.topic]) {
NSDictionary *data = message.data;
// Extract and validate revenue value
NSNumber *revenueNumber = data[@"revenue"];
double revenueValue = [revenueNumber doubleValue];
if (revenueValue > 0) {
// Create ad revenue data object
SingularAdData *adData = [[SingularAdData alloc]
initWithAdPlatform:@"AppLovin"
currency:@"USD"
revenue:revenueValue];
// Send to Singular
[Singular adRevenue:adData];
NSLog(@"Ad revenue sent: %f USD", revenueValue);
} else {
NSLog(@"Failed to parse valid revenue value or revenue is not greater than 0");
}
}
}
Unity LevelPlay (IronSource) 統合
IronSource SDKを使用して、ironSourceおよびメディエーションネットワークから インプレッション単位の収益をトラッキングします。
要件:
- ironSource SDKを実装してください ( スタートガイド を参照)
- IronSourceダッシュボードでARM SDK Postbacksフラグを有効化してください
- 収益コールバックを受信するために、impression dataリスナーを設定してください
詳細を見る: 完全なセットアップの詳細は IronSource広告収益ドキュメント を参照してください。
実装
impression data successコールバックを実装して収益をキャプチャおよび送信します。
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")
}
#import <Singular/Singular.h>
#import <IronSource/IronSource.h>
- (void)impressionDataDidSucceed:(ISImpressionData *)impressionData {
// Validate impression data
if (!impressionData) {
NSLog(@"No impression data available");
return;
}
// Extract and validate revenue
double revenue = impressionData.revenue;
if (revenue <= 0) {
NSLog(@"Invalid revenue value: %f", revenue);
return;
}
// Create ad revenue data object
SingularAdData *data = [[SingularAdData alloc]
initWithAdPlatform:@"IronSource"
currency:@"USD"
revenue:revenue];
// Send to Singular
[Singular adRevenue:data];
NSLog(@"Ad revenue sent: %f USD", revenue);
}
TradPlus統合
impression delegateを使用して、TradPlusメディエーションからの広告収益を キャプチャします。
要件:
-
TradPlus.sharedInstance().impressionDelegateを介してimpression delegateを設定してください -
収益データを受信するために
tradPlusAdImpressionコールバックを処理してください - eCPMをミリ単位から標準通貨単位に変換してください (1000で除算)
実装
すべての広告インプレッションと収益をトラッキングするために、impression delegate を登録します。
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)")
}
#import <Singular/Singular.h>
#import <TradPlusSDK/TradPlusSDK.h>
// Set up the delegate
TradPlus.sharedInstance.impressionDelegate = self;
// Delegate method for handling ad impressions
- (void)tradPlusAdImpression:(NSDictionary<NSString *, id> *)adInfo {
NSString *currency = @"USD";
// Extract and validate eCPM value
NSNumber *ecpmValue = adInfo[@"ecpm"];
if (!ecpmValue) {
NSLog(@"No eCPM data available in adInfo");
return;
}
// Convert eCPM from milli-units to dollars
double revenue = [ecpmValue doubleValue] / 1000.0;
// Validate revenue
if (revenue <= 0) {
NSLog(@"Ad Revenue value out of expected range: %f", revenue);
return;
}
// Create ad revenue data object
SingularAdData *data = [[SingularAdData alloc]
initWithAdPlatform:@"TradPlus"
currency:currency
revenue:revenue];
// Send to Singular
[Singular adRevenue:data];
NSLog(@"Ad revenue sent: %f %@", revenue, currency);
}
汎用統合 (その他のプラットフォーム)
汎用の
SingularAdData
インターフェースを使用して、任意のメディエーションプラットフォームを統合します。
要件:
- メディエーションプラットフォームからインプレッション単位の収益データに アクセスできること
- 標準通貨単位での収益額
- ISO 4217通貨コード (例: USD、EUR、INR)
データの正確性: Singularに送信する前に、収益と通貨データを 検証してください。誤ったデータは送信後に修正できません。
実装
プラットフォーム名、通貨、収益を含む
SingularAdData
オブジェクトを作成し、
Singular.adRevenue()
を呼び出します。
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)
#import <Singular/Singular.h>
- (void)reportAdRevenueWithPlatform:(NSString *)adPlatform
currency:(NSString *)currency
revenue:(double)revenue {
// Validate revenue
if (revenue <= 0) {
NSLog(@"Invalid revenue value: %f", revenue);
return;
}
// Validate currency
if (!currency || currency.length == 0) {
NSLog(@"Invalid currency: %@", currency);
return;
}
// Create ad revenue data object
SingularAdData *data = [[SingularAdData alloc]
initWithAdPlatform:adPlatform
currency:currency
revenue:revenue];
// Send to Singular
[Singular adRevenue:data];
NSLog(@"Revenue sent: %f %@ from %@", revenue, currency, adPlatform);
}
// Example usage
[self reportAdRevenueWithPlatform:@"MyMediationPlatform"
currency:@"USD"
revenue:0.05];
追加属性による広告データの拡張
SingularAdData は、インプレッション単位のメタデータ用のsetterメソッドを
公開しています。メディエーションプラットフォームから提供される場合、これらを使用して
プレースメント、広告ユニット、メディエーショングルーピング、精度の詳細でイベントを
拡張してください。
Android SDKとは異なり、
SingularAdData
のsetterは
void
を返し、チェーンできません。各setterは個別の行で呼び出してください。
| メソッド | 説明 |
|---|---|
setNetworkName:
|
ネットワーク名を上書きします (デフォルトはコンストラクタに渡された 広告プラットフォーム)。メディエーションで基盤となるネットワークが メディエーションプラットフォームと異なる場合に使用します。 |
setAdType:
|
広告フォーマット (例:
@"Rewarded"、
@"Interstitial"、
@"Banner")。
|
setGroupType:
|
メディエーションプラットフォームで定義された広告グループ分類。 |
setImpressionId:
|
インプレッションの一意の識別子。重複排除と照合に使用されます。 |
setAdPlacementName:
|
人間が読めるプレースメント名 (例:
@"level_complete")。
|
setAdUnitId:
|
プラットフォーム固有の広告ユニット識別子 (例: AdMobの場合
@"ca-app-pub-..."
)。
|
setAdUnitName:
|
人間が読める広告ユニット名。 |
setAdGroupId:
|
メディエーションプラットフォームの広告グループ識別子。 |
setAdGroupName:
|
人間が読める広告グループ名。 |
setAdGroupPriority:
|
メディエーションウォーターフォール内で広告グループに割り当てられた優先度。 |
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に正しく流れていることを確認するために、広告収益の実装を テストしてください。
- ログの確認: 正しい値と通貨で収益コールバックログが 表示されることを確認
- テスト広告: 収益イベントをトリガーするために、 テスト広告をロードして表示
- ダッシュボードの検証: 24時間以内にSingularダッシュボード に収益が表示されることを確認
- データの正確性: 収益額がメディエーションプラットフォーム のレポートと一致することを検証
トラブルシューティング: Singularに収益が表示されない場合は、 以下を確認してください:
- Singularアカウントで広告収益アトリビューションが有効化されている
- 収益値が0より大きい
- 通貨コードが有効なISO 4217コードである
- プラットフォーム名がSingularの想定する形式と一致している