前段時間,蘋果終於在大陸區開放了應用商店的競價廣告。毫無疑問又開啟了蘋果應用導量的新玩法,各大廠商都緊跟腳步吃螃蟹。本篇講解蘋果廣告中的歸因部分。

蘋果廣告其實在海外已執行多年,而因為IDFA的政策變動,現在蘋果有新舊兩套歸因框架,通常我們都要接入。

一、iAd 和 AdServices 框架概述

iAd 框架:適用於iOS14.3以下版本,基於IDFA,需要使用者允許使用IDFA。尤其iOS14.0起,IDFA的政策變動,要接入ATT追蹤框架。

  歸因流程:開啟APP -> 呼叫iAd框架 -> 讀取廣告因素(JSON) -> 傳送廣告因素到後端 -> 傳送啟用日誌到後端

AdServices 框架:適用於iOS14.3及以上版本,不需使用者授權。

  歸因流程:開啟APP -> 呼叫AdServices框架 -> 讀取token -> 傳送token到蘋果後端換取廣告因素(JSON) -> 傳送廣告因素到後端 -> 傳送啟用日誌到後端

兩框架在流程上區別不大,得到資料也類似,主要區別是AdServices只有ID,沒有具體的名字。詳細JSON欄位:

兩套框架都要接,詳細區別不大,主要是跟iOS版本相關

區別 iAd AdServices
歸因視窗期 30天 30天
ATT影響 支援ATT Opt-In 不影響
歸因誤差率 15%-70%不等 10%左右或更低
資料延遲 三方MMP資料稱3秒內返回結果比例大於50% 三方MMP資料稱延遲0.5-1秒
引數豐富度 較全 較少(只返回ID)
是否支援展示歸因和指紋資訊歸因 不支援 不支援
是否支援非AppStore上架APP(越獄包) 不支援 不支援

▲▲▲高版本(14.5+)的idfa獲取,要等待彈窗被使用者授權後才能得到,所以需要延遲呼叫廣告歸因和啟用日誌:

+(void)initSDK{
//... ...
//蘋果ASA;延遲4秒再發送,等ATT使用者操作結果,可能有IDFA
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MySDK LogAds];
});
//啟用日誌;延遲6秒再發送,先讓Ads傳送完再發
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MySDK LogOpen];
});
//... ...
}

二、與第三方廣告的歸因的區別

1、第三方廣告(如頭條快手)使用的是廣告點選的監測短鏈,由廣告商回傳給我們後臺;蘋果採用的是iAd和AdServices,由接入的蘋果SDK傳送引數到我們後臺;

第三廣告的監測短鏈示例:

https://api.myhost.com/ad/toutiao/click?adkey=abcde&idfa=__IDFA__&ip=__IP__&os=__OS__&callback=__CALLBACK__

蘋果ASA的客戶端回傳示例:

https://api.myhost.com/ad/asa/click?idfa=xxxx&orgId=1234&campaignId=123456&adGroupId=123456&keywordId=12345678

(注意客戶端回傳的引數,若沒有增加IP地址的引數,則需要服務端讀取請求者的IP地址,以作歸因引數)

2、第三方廣告在點選時回傳,蘋果廣告在應用開啟時回傳;

3、第三方廣告使用自定義的adkey作為廣告依據,蘋果廣告建議使用蘋果的廣告組ID(adGroupId)作為後臺廣告依據;

廣告組ID可以在蘋果投放後臺右上角檢視,如圖

    

自己BI後臺的廣告列表示例:

廣告序號 廣告名稱 應用 渠道 adKey標識 廣告短鏈 渠道廣告ID
12323 頭條廣告001 遊戲A 頭條1 abcde https://api.myhost.com/... (無)
12324 蘋果廣告001 遊戲A 蘋果1     123456

三、蘋果端SDK的接入

1、準備條件,開發環境 Xcode12.3+,MacOS11+。如果版本不滿足,則需更新開發軟體(和系統)。

2、接入方法,新增iAd到Xcode專案:

  1)選擇專案主檔案 > TARGETS > General

  

  2)引入 iAd.framework、AdServices.framwork、AdSupport.framwork

  

  3)進入 Link Binary With Libraries,將上述3個框架都改為Optional

  

4、程式碼  MySDK.m(Objective-C)

/** 匯入上述3個框架*/
#import <iAd/iAd.h>
#import <AdServices/AdServices.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h> /** 蘋果Ads廣告*/
/** TODO:有些舊裝置新系統,會出現token為空的問題*/
+(void)LogAds{
// 14.3之後
if (@available(iOS 14.3, *)) {
NSError *error;
NSString *token = [AAAttribution attributionTokenWithError:&error];
NSLog(@"LogAds:AdServces,Token: %@", token);
if (token != nil) {
// 1、傳送POST給蘋果得到歸因資料
[MySDK sendToken:[MySDK getANullableString:@"token" content:token] completeBlock:^(NSDictionary *attrData) {
//非同步,會延後
NSLog(@"LogAds:14.3+ Dict: %@", attrData);
//TODO::傳送資料給服務端
// ... ...
}];
} // 14.3之前
} else {
if ([[ADClient sharedClient] respondsToSelector:@selector(requestAttributionDetailsWithBlock:)]) {
NSLog(@"LogAds:iAd called");
[[ADClient sharedClient] requestAttributionDetailsWithBlock:^(NSDictionary *attrData, NSError *error) {
//非同步,會延後
NSLog(@"LogAds:14- Dict: %@", attrData);
//TODO::傳送資料給服務端
// ... ...
}];
}
}
} /** 讀取可能為空的字串*/
+(nullable NSString *)getANullableString:(NSString *)desc content:(NSString *)content{
if(content == nil){
return @"";
}
return [NSString stringWithFormat:@"%@", content];
} /** 傳送歸因token得到資料 */
+(void)sendToken:(NSString *)token completeBlock:(void(^)(NSDictionary* data))completeBlock{
NSString *url = [NSString stringWithFormat:@"https://api-adservices.apple.com/api/v1/"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
request.HTTPMethod = @"POST";
[request addValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
NSData* postData = [token dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary * result = NULL;
if (error) {
//請求失敗
NSLog(@"LogAds:sendToken ERR");
if (completeBlock) {
NSMutableDictionary *nulldict = [NSMutableDictionary dictionary];
completeBlock(nulldict);
}
}else{
// 請求成功
NSError *resError;
NSMutableDictionary *resDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&resError];
result = [[NSDictionary alloc] initWithDictionary:resDic];
if (completeBlock) {
completeBlock(result);
}
}
}];
[dataTask resume];
}

至此,蘋果ASA的廣告歸因接入告一段落

待後臺對接好廣告歸因邏輯程式碼,蘋果包上架應用商店,就可以了。

附:IDFA的新舊版本的接入

#import <AppTrackingTransparency/AppTrackingTransparency.h>

-(void)initSDK{
//... ...
//IDFA iOS14不同方式
if (@available(iOS 14, *)) {
// iOS14及以上版本需要先請求許可權
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
// 獲取到許可權後,依然使用老方法獲取idfa
// iOS14以後,idfa在回撥之後才能獲得,應當等回撥後再發送日誌
if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
self->_idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
}
}];
}else{
_idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
//... ...
}