前段時間,蘋果終於在大陸區開放了應用商店的競價廣告。毫無疑問又開啟了蘋果應用導量的新玩法,各大廠商都緊跟腳步吃螃蟹。本篇講解蘋果廣告中的歸因部分。
蘋果廣告其實在海外已執行多年,而因為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];
- }
- //... ...
- }