알립니다
이 기능은 베타 서비스입니다. 개선 의견과 문의사항은 에어브릿지 CSM을 통해 전달해 주세요. 담당 CSM이 없는 경우 문의하기를 통해 전달해 주세요. 정식 서비스에서 발전한 기능으로 보답하겠습니다.
에어브릿지와 얀덱스 모바일 애즈(Yandex Mobile Ads) 를 연동해 광고로 발생한 수익과 관련된 데이터를 에어브릿지 대시보드에서 확인할 수 있습니다. 에어브릿지는 얀덱스 모바일 애즈 SDK와 SDK 연동을 지원합니다.
아래 링크에 따라 얀덱스 모바일 애즈 SDK 설치해 주세요.
얀덱스 모바일 애즈 SDK에서 발생한 광고 노출(Ad impression) 데이터를 에어브릿지로 전송합니다. 광고를 보여줄 때 광고 노출 데이터를 에어브릿지 SDK로 전송합니다.
data class ImpressionDataModel(
val ad_unit_id: String,
val adType: String,
val currency: String,
val revenue: String,
val revenueUSD: String,
val precision: String,
val network: NetworkData
)
data class NetworkData(
val name: String,
val ad_unit_id: String
)
class ExampleNativeAdEventListener : NativeAdEventListener {
// ...
override fun onImpression(data: ImpressionData?) {
val impressionData = data?.rawData?.let {
try {
Gson().fromJson(it, ImpressionDataModel::class.java)
} catch (_: Throwable) {
null
}
} ?: return
Airbridge.trackEvent(
AirbridgeCategory.AD_IMPRESSION, mutableMapOf(
AirbridgeAttribute.ACTION to impressionData.network.name,
AirbridgeAttribute.LABEL to impressionData.adType,
AirbridgeAttribute.VALUE to impressionData.revenue.toDoubleOrNull(),
AirbridgeAttribute.CURRENCY to impressionData.currency,
AirbridgeAttribute.AD_PARTNERS to mapOf(
"yandex" to mapOf(
"revenue" to impressionData.revenue,
"revenue_usd" to impressionData.revenueUSD,
"precision" to impressionData.precision,
"ad_unit_id" to impressionData.ad_unit_id,
"ad_network" to impressionData.network.name,
"ad_network_ad_unit_id" to impressionData.network.ad_unit_id,
)
)
)
)
}
// ...
}
public class ExampleNativeAdEventListener implements NativeAdEventListener {
class ImpressionDataModel {
String ad_unit_id;
String adType;
String currency;
String revenue;
String revenueUSD;
String precision;
NetworkData network;
}
class NetworkData {
String name;
String ad_unit_id;
}
@Override
public void onImpression(@Nullable ImpressionData data) {
if (data == null || data.getRawData() == null) {
return;
}
ImpressionDataModel impressionData;
try {
impressionData = new Gson().fromJson(data.getRawData(), ImpressionDataModel.class);
} catch (Throwable throwable) {
return;
}
Airbridge.trackEvent(
AirbridgeCategory.AD_IMPRESSION,
new HashMap<String, Object>() {{
put(AirbridgeAttribute.ACTION, impressionData.network.name);
put(AirbridgeAttribute.LABEL, impressionData.adType);
try {
put(AirbridgeAttribute.VALUE, Double.parseDouble(impressionData.revenue));
} catch (NumberFormatException e) {
// Handle exception
}
put(AirbridgeAttribute.CURRENCY, impressionData.currency);
put(AirbridgeAttribute.AD_PARTNERS, new HashMap<String, Object>() {{
put("yandex", new HashMap<String, Object>() {{
put("revenue", impressionData.revenue);
put("revenue_usd", impressionData.revenueUSD);
put("precision", impressionData.precision);
put("ad_unit_id", impressionData.ad_unit_id);
put("ad_network", impressionData.network.name);
put("ad_network_ad_unit_id", impressionData.network.ad_unit_id);
}});
}});
}});
}
}
data class ImpressionDataModel(
val ad_unit_id: String,
val adType: String,
val currency: String,
val revenue: String,
val revenueUSD: String,
val precision: String,
val network: NetworkData
)
data class NetworkData(
val name: String,
val ad_unit_id: String
)
class ExampleNativeAdEventListener : NativeAdEventListener {
// ...
override fun onImpression(data: ImpressionData?) {
val impressionData = data?.rawData?.let {
try {
Gson().fromJson(it, ImpressionDataModel::class.java)
} catch (_: Throwable) {
null
}
} ?: return
val event = Event("airbridge.adImpression")
val yandex = mutableMapOf<String, Any?>()
yandex["revenue"] = impressionData.revenue
yandex["revenue_usd"] = impressionData.revenueUSD
yandex["precision"] = impressionData.precision
yandex["ad_unit_id"] = impressionData.ad_unit_id
yandex["ad_network"] = impressionData.network.name
yandex["ad_network_ad_unit_id"] = impressionData.network.ad_unit_id
val adPartners = mapOf("yandex" to yandex)
event.action = impressionData.network.name
event.label = impressionData.adType
impressionData.revenue.toDoubleOrNull()?.let {
event.value = it
}
event.semanticAttributes = mutableMapOf(
"adPartners" to adPartners,
"currency" to impressionData.currency
)
Airbridge.trackEvent(event)
}
// ...
}
public class ExampleNativeAdEventListener implements NativeAdEventListener {
class ImpressionDataModel {
String ad_unit_id;
String adType;
String currency;
String revenue;
String revenueUSD;
String precision;
NetworkData network;
}
class NetworkData {
String name;
String ad_unit_id;
}
@Override
public void onImpression(@Nullable ImpressionData data) {
if (data == null || data.getRawData() == null) {
return;
}
ImpressionDataModel impressionData;
try {
impressionData = new Gson().fromJson(data.getRawData(), ImpressionDataModel.class);
} catch (Throwable throwable) {
return;
}
Event event = new Event("airbridge.adImpression");
Map<String, Object> yandex = new HashMap<>();
yandex.put("revenue", impressionData.revenue);
yandex.put("revenue_usd", impressionData.revenueUSD);
yandex.put("precision", impressionData.precision);
yandex.put("ad_unit_id", impressionData.ad_unit_id);
yandex.put("ad_network", impressionData.network.name);
yandex.put("ad_network_ad_unit_id", impressionData.network.ad_unit_id);
Map<String, Object> adPartners = new HashMap<>();
adPartners.put("yandex", yandex);
Map<String, Object> semanticAttributes = new HashMap<>();
semanticAttributes.put("adPartners", adPartners);
semanticAttributes.put("currency", impressionData.currency);
event.setAction(impressionData.network.name);
event.setLabel(impressionData.adType);
try {
event.setValue(Double.parseDouble(impressionData.revenue));
} catch (NumberFormatException e) {
// Handle exception
}
event.setSemanticAttributes(semanticAttributes);
Airbridge.trackEvent(event);
}
}
struct NetworkData: Decodable {
let name: String
let ad_unit_id: String
}
struct ImpressionDataModel: Decodable {
let ad_unit_id: String
let adType: String
let currency: String
let revenue: String
let revenueUSD: String
let precision: String
let network: NetworkData
}
extension ViewController: AdViewDelegate {
// ...
func adView(_ adView: AdView, didTrackImpressionWith impressionData: ImpressionData?) {
guard
let raw = impressionData?.rawData,
let jsonData = raw.data(using: .utf8)
else {
return
}
do {
let parsedData = try JSONDecoder().decode(ImpressionDataModel.self, from: jsonData)
var semanticAttributes: [String: Any] = [
AirbridgeAttribute.ACTION: parsedData.network.name,
AirbridgeAttribute.LABEL: parsedData.adType,
AirbridgeAttribute.CURRENCY: parsedData.currency,
AirbridgeAttribute.AD_PARTNERS: [
"yango": [
"revenue": parsedData.revenue,
"revenue_usd": parsedData.revenueUSD,
"precision": parsedData.ad_unit_id,
"ad_unit_id": parsedData.network.ad_unit_id,
"ad_network": parsedData.network.name,
"ad_network_ad_unit_id": parsedData.precision
]
]
]
if let value = Double(parsedData.revenue) {
semanticAttributes[AirbridgeAttribute.VALUE] = value
}
Airbridge.trackEvent(
category: AirbridgeCategory.AD_IMPRESSION,
semanticAttributes: semanticAttributes
)
} catch {
print("Failed to parse JSON: \(error.localizedDescription)")
}
}
}
@interface NetworkData : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *ad_unit_id;
@end
@implementation NetworkData
@end
@interface ImpressionDataModel : NSObject
@property (nonatomic, strong) NSString *ad_unit_id;
@property (nonatomic, strong) NSString *adType;
@property (nonatomic, strong) NSString *currency;
@property (nonatomic, strong) NSString *revenue;
@property (nonatomic, strong) NSString *revenueUSD;
@property (nonatomic, strong) NSString *precision;
@property (nonatomic, strong) NetworkData *network;
@end
@implementation ImpressionDataModel
@end
@implementation ViewController
- (void)adView:(AdView *)adView didTrackImpressionWith:(ImpressionData *)impressionData {
NSString *raw = impressionData.rawData;
if (!raw) return;
NSData *jsonData = [raw dataUsingEncoding:NSUTF8StringEncoding];
if (!jsonData) return;
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if (error) {
NSLog(@"Failed to parse JSON: %@", error.localizedDescription);
return;
}
ImpressionDataModel *parsedData = [[ImpressionDataModel alloc] init];
parsedData.ad_unit_id = dict[@"ad_unit_id"];
parsedData.adType = dict[@"adType"];
parsedData.currency = dict[@"currency"];
parsedData.revenue = dict[@"revenue"];
parsedData.revenueUSD = dict[@"revenueUSD"];
parsedData.precision = dict[@"precision"];
NSDictionary *networkDict = dict[@"network"];
if ([networkDict isKindOfClass:[NSDictionary class]]) {
NetworkData *network = [[NetworkData alloc] init];
network.name = networkDict[@"name"];
network.ad_unit_id = networkDict[@"ad_unit_id"];
parsedData.network = network;
}
NSMutableDictionary *semanticAttributes = [NSMutableDictionary dictionary];
semanticAttributes[AirbridgeAttribute.ACTION] = parsedData.network.name;
semanticAttributes[AirbridgeAttribute.LABEL] = parsedData.adType;
double revenueValue = [parsedData.revenue doubleValue];
if (revenueValue > 0) {
semanticAttributes[AirbridgeAttribute.VALUE] = revenueValue;
}
semanticAttributes[AirbridgeAttribute.CURRENCY] = parsedData.currency;
semanticAttributes[AirbridgeAttribute.AD_PARTNERS] = @{
@"yango": @{
@"revenue": parsedData.revenue,
@"revenue_usd": parsedData.revenueUSD,
@"precision": parsedData.ad_unit_id,
@"ad_unit_id": parsedData.network.ad_unit_id,
@"ad_network": parsedData.network.name,
@"ad_network_ad_unit_id": parsedData.precision
}
}
[Airbridge trackEventWithCategory:AirbridgeCategory.AD_IMPRESSION
semanticAttributes:semanticAttributes];
}
@end
struct NetworkData: Decodable {
let name: String
let ad_unit_id: String
}
struct ImpressionDataModel: Decodable {
let ad_unit_id: String
let adType: String
let currency: String
let revenue: String
let revenueUSD: String
let precision: String
let network: NetworkData
}
extension ViewController: AdViewDelegate {
// ...
func adView(_ adView: AdView, didTrackImpressionWith impressionData: ImpressionData?) {
guard
let raw = impressionData?.rawData,
let jsonData = raw.data(using: .utf8)
else {
return
}
do {
let parsedData = try JSONDecoder().decode(ImpressionDataModel.self, from: jsonData)
let event = ABInAppEvent()
event?.setCategory("airbridge.adImpression")
event?.setAction(parsedData.network.name)
event?.setLabel(parsedData.adType)
if let value = Double(parsedData.revenue) {
event?.setValue(value)
}
event?.setSemantics([
"adPartners": [
"yango": [
"revenue": parsedData.revenue,
"revenue_usd": parsedData.revenueUSD,
"precision": parsedData.ad_unit_id,
"ad_unit_id": parsedData.network.ad_unit_id,
"ad_network": parsedData.network.name,
"ad_network_ad_unit_id": parsedData.precision
]
],
"currency": parsedData.currency
])
event?.send()
} catch {
print("Failed to parse JSON: \(error.localizedDescription)")
}
}
}
@interface NetworkData : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *ad_unit_id;
@end
@implementation NetworkData
@end
@interface ImpressionDataModel : NSObject
@property (nonatomic, strong) NSString *ad_unit_id;
@property (nonatomic, strong) NSString *adType;
@property (nonatomic, strong) NSString *currency;
@property (nonatomic, strong) NSString *revenue;
@property (nonatomic, strong) NSString *revenueUSD;
@property (nonatomic, strong) NSString *precision;
@property (nonatomic, strong) NetworkData *network;
@end
@implementation ImpressionDataModel
@end
@implementation ViewController
- (void)adView:(AdView *)adView didTrackImpressionWith:(ImpressionData *)impressionData {
NSString *raw = impressionData.rawData;
if (!raw) return;
NSData *jsonData = [raw dataUsingEncoding:NSUTF8StringEncoding];
if (!jsonData) return;
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if (error) {
NSLog(@"Failed to parse JSON: %@", error.localizedDescription);
return;
}
ImpressionDataModel *parsedData = [[ImpressionDataModel alloc] init];
parsedData.ad_unit_id = dict[@"ad_unit_id"];
parsedData.adType = dict[@"adType"];
parsedData.currency = dict[@"currency"];
parsedData.revenue = dict[@"revenue"];
parsedData.revenueUSD = dict[@"revenueUSD"];
parsedData.precision = dict[@"precision"];
NSDictionary *networkDict = dict[@"network"];
if ([networkDict isKindOfClass:[NSDictionary class]]) {
NetworkData *network = [[NetworkData alloc] init];
network.name = networkDict[@"name"];
network.ad_unit_id = networkDict[@"ad_unit_id"];
parsedData.network = network;
}
ABInAppEvent* event = [[ABInAppEvent alloc] init];
[event setCategory:@"airbridge.adImpression"];
[event setAction:parsedData.network.name];
[event setLabel:parsedData.adType];
double revenueValue = [parsedData.revenue doubleValue];
if (revenueValue > 0) {
[event setValue:revenueValue];
}
[event setSemantics:@{
@"adPartners": @{
@"yango": @{
@"revenue": parsedData.revenue,
@"revenue_usd": parsedData.revenueUSD,
@"precision": parsedData.ad_unit_id,
@"ad_unit_id": parsedData.network.ad_unit_id,
@"ad_network": parsedData.network.name,
@"ad_network_ad_unit_id": parsedData.precision
}
},
@"currency": parsedData.currency
}];
[event send];
}
@end
[Serializable]
public class ImpressionDataModel
{
public string ad_unit_id;
public string adType;
public string currency;
public string revenue;
public string revenueUSD;
public string precision;
public NetworkData network;
}
[Serializable]
public class NetworkData
{
public string name;
public string ad_unit_id;
}
class ExampleNativeAdEventListener : NativeAdEventListener
{
// ...
public void HandleImpression(object sender, ImpressionData impressionData)
{
var data = impressionData == null ? "null" : impressionData.rawData;
try
{
var parsedData = Newtonsoft.Json.JsonConvert.DeserializeObject<ImpressionDataModel>(data);
var semanticAttributes = new Dictionary<string, object>()
{
{ AirbridgeAttribute.ACTION, parsedData.network.name },
{ AirbridgeAttribute.LABEL, parsedData.adType },
{ AirbridgeAttribute.CURRENCY, parsedData.currency },
{
AirbridgeAttribute.AD_PARTNERS, new Dictionary<string, object>()
{
"yango", new Dictionary<string, object>()
{
{ "revenue", parsedData.revenue },
{ "revenue_usd", parsedData.revenueUSD }
{ "precision", parsedData.precision },
{ "ad_unit_id", parsedData.ad_unit_id },
{ "ad_network", parsedData.network.name },
{ "ad_network_ad_unit_id", parsedData.network.ad_unit_id }
}
}
}
}
if (double.TryParse(parsedData.revenue, out double result))
{
semanticAttributes[AirbridgeAttribute.VALUE] = result;
}
Airbridge.TrackEvent(
category: AirbridgeCategory.AD_IMPRESSION,
semanticAttributes: semanticAttributes
);
}
catch (Exception ex)
{
Debug.LogError($"Error parsing impression data: {ex.Message}");
}
}
//..
}
[Serializable]
public class ImpressionDataModel
{
public string ad_unit_id;
public string adType;
public string currency;
public string revenue;
public string revenueUSD;
public string precision;
public NetworkData network;
}
[Serializable]
public class NetworkData
{
public string name;
public string ad_unit_id;
}
class ExampleNativeAdEventListener : NativeAdEventListener
{
// ...
public void HandleImpression(object sender, ImpressionData impressionData)
{
var data = impressionData == null ? "null" : impressionData.rawData;
try
{
var parsedData = Newtonsoft.Json.JsonConvert.DeserializeObject<ImpressionDataModel>(data);
AirbridgeEvent @event = new AirbridgeEvent("airbridge.adImpression");
var yango = new Dictionary<string, object>();
yango["revenue"] = parsedData.revenue;
yango["revenue_usd"] = parsedData.revenueUSD;
yango["precision"] = parsedData.precision;
yango["ad_unit_id"] = parsedData.ad_unit_id;
yango["ad_network"] = parsedData.network.name;
yango["ad_network_ad_unit_id"] = parsedData.network.ad_unit_id;
var adPartners = new Dictionary<string, object>();
adPartners["yango"] = yango;
@event.SetAction(parsedData.network.name);
@event.SetLabel(parsedData.adType);
if (double.TryParse(parsedData.revenue, out double result))
{
@event.SetValue(result);
}
@event.AddSemanticAttribute("adPartners", adPartners);
@event.AddSemanticAttribute("currency", parsedData.currency);
AirbridgeUnity.TrackEvent(@event);
}
catch (Exception ex)
{
Debug.LogError($"Error parsing impression data: {ex.Message}");
}
}
//..
}
도움이 되었나요?