AdServices归因和iAd归因集成
AdServices framework 是 Apple 专门为 ASA 提供的归因框架 。尤其在ATT 政策推出以后,app 获取用户 IDFA 的比例大幅降低,传统的依靠IDFA 的方法也无法准确归因。
但是 Apple 为 ASA 开了一个后门,其他广告渠道无法获取用户的 IDFA 作为身份标识符进行归因,而 ASA 可以获取一个甚至比 IDFA 更好的用户token 进行归因-因为即便 ATT 之前,用户在 iPhone 的设置也会导致无法完全获取 IDFA,但是 ASA 的用户 token ,只要接入 AdServicesframework,就可以获取到。
另外要注意的是,除了 AdServices framework, ASA 还有一个 iAdframework。但是后者仅适用于 ioS 14.3 之前版本,且此框架已经停用iOS 14.3 之前的用户占比也很小,所以不接入对归因也没有太大影响,所以这节课不会涉及 iAd framework。
官方文档
https://ads.apple.com/cn/help/reporting/0028-apple-ads-attribution-api
AdServices 接入目的
通过 AdServices framework,可以让我们对每一个激活用户获取一个Token 标识符,用此 Token 可以得知该用户是否点击过 ASA 广告、点击过那个广告系列/广告组/关键词/素材等广告信息。
AdServices 接入步骤
1.选择项目主文件-TARGETS-General
2.入 AdServices framework
3.进入 link binary with Libraries 将 AdServices 改为 optional
4.导入AdServices framework
5.添加获取用户 Token 的代码
6.更新 App 并发布至 App Store
AdServices 接入流程

AdServices归因和iAd归因集成
前提:AdServices归因框架的集成必须是iOS14.3以上版本,xcode版本12.3以上;旧版本依旧使⽤iAd 归因框架。
第一步:找到framework的添加入

添加framework
第二步:分别搜索AdServices.framework、AdSupport.framework、iAd.framework,进行添加

AdServices.framework

AdSupport.framework

iAd.framework
第三步:在Build Phases中Link Binary With Libraries 修改 AdServices.framework、AdSupport.framework、iAd.framework的类型为Optional

AdServices.framework、AdSupport.framework、iAd.framework的类型为Optional
第四部:将AdServices.framework、AdSupport.framework、iAd.framework的头文件加入到项目
#pragma mark -- 归因
#import "iAd/iAd.h"
#import "AdServices/AdServices.h"
#import "AppTrackingTransparency/AppTrackingTransparency.h"
添加头文件
第五步:代码集成,可在AppDelegate中添加
5.1 AdServices获取token
+(void)getAdToken
{if (@available(iOS 14.3, *)) {NSError *error;NSString *token = [AAAttribution attributionTokenWithError:&error];if (token != nil) {// 发送POST请求归因数据[self sendToken:[self getANullableString:@"token" content:token]completeBlock:^(NSDictionary *attrData) {NSLog(@"成功==:14.3+ Dict: %@", attrData);//可将数据发送给服务端}];}} else {// 老版本请求if ([[ADClient sharedClient]respondsToSelector:@selector(requestAttributionDetailsWithBlock:)]) {NSLog(@"LogAds:iAd called");[[ADClient sharedClient]requestAttributionDetailsWithBlock:^(NSDictionary *attrData, NSError *error) {//异步,会延后NSLog(@"成功:14- Dict: %@", attrData);//可将数据发送给服务端// ... ...}];}}
}
5.2 AdServices获取归因数据
/** 读取可能为空的字符串*/
-(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{// 请求成功NSLog(@"请求成功");NSError *resError;NSMutableDictionary *resDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&resError];result = [[NSDictionary alloc] initWithDictionary:resDic];if (completeBlock) {completeBlock(result);}}}];[dataTask resume];
}
5.3 AdServices 返回归因数据包示例
经测试,IDFA允许用户跟踪后,得到的数据是详细数据包
{
adGroupId = 1234567890;
attribution = 1;
campaignId = 1234567890;
clickDate = "2022-04-27T07:59Z";
conversionType = Download;
countryOrRegion = US;
creativeSetId = 1234567890;
keywordId = 12323222;
orgId = 1234567890;
}
未允许,得到的数据是标准数据包,没有clickDate字段
{
"attribution": true,
"orgId": 40669820,
"campaignId": 542370539,
"conversionType": "Download",
"adGroupId": 542317095,
"countryOrRegion": "US",
"keywordId": 87675432,
"creativeSetId": 542317136
}
5.4 iAd 代码
// 老版本请求
if ([[ADClient sharedClient]respondsToSelector:@selector(requestAttributionDetailsWithBlock:)]) {NSLog(@"LogAds:iAd called");[[ADClient sharedClient]requestAttributionDetailsWithBlock:^(NSDictionary *attrData, NSError *error) {//异步,会延后NSLog(@"成功:14- Dict: %@", attrData);//可将数据发送给服务端// ... ...}];
}
5.5iAd返回归因数据包示例
{
"iad-adgroup-id" = 1234567890;
"iad-adgroup-name" = AdGroupName;
"iad-attribution" = true;
"iad-campaign-id" = 1234567890;
"iad-campaign-name" = CampaignName;
"iad-click-date" = "2022-04-27T07:31:36Z";
"iad-conversion-date" = "2022-04-27T07:31:36Z";
"iad-conversion-type" = Download;
"iad-country-or-region" = US;
"iad-creativeset-id" = 1234567890;
"iad-creativeset-name" = CreativeSetName;
"iad-keyword" = Keyword;
"iad-keyword-id" = 12323222;
"iad-keyword-matchtype" = Broad;
"iad-lineitem-id" = 1234567890;
"iad-lineitem-name" = LineName;
"iad-org-id" = 1234567890;
"iad-org-name" = OrgName;
"iad-purchase-date" = "2022-04-27T07:31:36Z";
};

相关文章:
AdServices归因和iAd归因集成
AdServices framework 是 Apple 专门为 ASA 提供的归因框架 。尤其在ATT 政策推出以后,app 获取用户 IDFA 的比例大幅降低,传统的依靠IDFA 的方法也无法准确归因。 但是 Apple 为 ASA 开了一个后门,其他广告渠道无法获取用户的 IDFA 作为身份…...
关于 内部类 你了解多少?(详解!!)
目录 1. 什么是内部类? 2. 内部类的分类 3. 内部类 3.1 实例内部类 3.2 静态内部类 4. 局部内部类 5. 匿名内部类 6.对象的打印 “不积跬步无以至千里,不积小流无以成江海。”每天坚持学习,哪怕是一点点!!&a…...
CNVD-2021-09650:锐捷NBR路由器(guestIsUp.php)RCE漏洞复现 [附POC]
文章目录 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC] 0x01 前言 免…...
如何在Docker部署Draw.io绘图工具并远程访问
文章目录 前言1. 使用Docker本地部署Drawio2. 安装cpolar内网穿透工具3. 配置Draw.io公网访问地址4. 公网远程访问Draw.io 前言 提到流程图,大家第一时间可能会想到Visio,不可否认,VIsio确实是功能强大,但是软件为收费࿰…...
Android APK打包的过程主要步骤
Android APK打包的过程可以概括为以下几个主要步骤: 编译源代码:将开发好的Java源代码编译成Dalvik字节码文件(.dex文件),Android安卓该文件包含了Android平台上的运行程序的指令集。打包资源文件:将应用程…...
吃透 Spring 系列—MVC部分
目录 ◆ SpringMVC简介 - SpringMVC概述 - SpringMVC快速入门 - Controller中访问容器中的Bean - SpringMVC关键组件浅析 ◆ SpringMVC的请求处理 - 请求映射路径的配置 - 请求数据的接收 - Javaweb常用对象获取 - 请求静态资源 - 注解驱动 标签 ◆ SpringMV…...
Java面试题(每天10题)-------连载(32)
目录 设计模式篇 1、工厂方法模式(利用创建同一接口的不同实例): 2、抽象工厂模式(多个工厂) 3、单例模式(保证对象只有一个实例) 4、原型模式(对一个原型进行复制、克隆产生类…...
HDP集群Kafka开启SASLPLAINTEXT安全认证
hdp页面修改kafka配置 java代码连接kafka增加对应的认证信息 props.put("security.protocol","SASL_PLAINTEXT");props.put("sasl.mechanism","PLAIN");props.put("sasl.jaas.config","org.apache.kafka.common.securi…...
判断上颌下颌的stl模型坐标轴是否正常
文章目录 研究方向:如何判断?又如何纠正?如何判断?Demo实现:先判断一个遍历相关文件夹下的所有病例如何纠正?Demo相关知识点研究方向:如何判断?又如何纠正? 如何判断? 当然,我们不能以坐标的正负来判断 我们看到这个Bounding Box里面有stl模型的xyz三轴方向的最大值与最…...
C/C++---------------LeetCode第1189. “气球” 的最大数量
气球的最大数量 题目及要求统计法在main内使用 题目及要求 给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”(气球)。 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “ba…...
Arthas(阿尔萨斯)--(三)
目录 一、Arthas学习 1、class/classloader相关命令一 1、sc 2、sm 2、class/classloader相关命令二 1、jad 2、mc 3、redefine 三、class/classloader相关命令三 一、Arthas学习 Arthas(阿尔萨斯)--(一) Arthas(阿尔萨斯)--(二) 1、class/classloader相关命令一 …...
《变形监测与数据处理》笔记/期末复习资料(择期补充更新)
变形: 变形是物体在外来因素作用下产生的形状、大小及位置的变化(随时间域和空间域的变化),它是自然界普遍存在的现象。 变形体: 一般包括工程建筑物、构筑物、大型机械设备以及其他自然和人工对象等。 变形体和变形…...
Linux:进程替换和知识整合
文章目录 进程程序替换替换原理进程替换的理解 环境变量与进程替换命令行解释器实现逻辑 进程程序替换 前面已经学习了子进程的创建,但是子进程的创建不管怎么说,都是父进程代码的一部分,那么实际上如果想要子进程执行新的程序呢?…...
React组件在什么情况下会重新渲染
当我们使用React编写组件时,组件的重新渲染是一个重要的概念。重新渲染是指React组件在特定情况下会重新执行其渲染函数,更新用户界面以反映最新的数据。很多情况下,组件不必要的重新渲染会严重影响性能,所以要充分了解触发组件重…...
云ES容灾方案
一、ES集群可用性容灾 1.1 云ES集群可用性容灾(使用跨可用区实例) 云ES集群部署在三个可用区,单可用区故障,云ES集群依然可能对外提供服务;两个可用区故障,需要进行控制台切流(集群会自动切的选择主节点) 应用服务部署在二个可用区,单可用区故障,依然可对提供服务1.2 …...
Golang 中的 Context 包
简介 今天,我们将讨论 Go 编程中非常重要的一个主题:context 包。如果你现在觉得它很令人困惑,不用担心 — 在本文结束时,你将像专家一样处理 context! 想象一下,你在一个主题公园,兴奋地准备…...
nginx服务器
nginx反向代理 nginx 反向代理的好处: 提高访问速度 因为nginx本身可以进行缓存,如果访问的同一接口,并且做了数据缓存, nginx就直接可把数据返回,不需要真正地访问服务端,从而提高访问速度。 进行负载均衡…...
电脑常用快捷键
一、Win键(徽标键) 以下是Windows操作系统中使用Win键(徽标键)结合A-Z的所有快捷方式描述: - Win A:打开操作中心,访问系统通知、快速设置和其他功能 - Win B:将焦点设置到任务栏…...
吴恩达《机器学习》8-3->8-4:模型表示I、模型表示II
8.3、模型表示I 一、大脑神经网络的基本原理 为了构建神经网络模型,首先需要理解大脑中的神经网络是如何运作的。每个神经元都可以被看作是一个处理单元或神经核,它包含多个输入(树突)和一个输出(轴突)。…...
数据结构-二叉树力扣题
目录 1.相同的树 2.二叉树中查找值为x的节点 3.单值二叉树 4.对称二叉树 5.二叉树的前序遍历 6.另一颗树的子树 层序遍历: 7.二叉树遍历 8.判断二叉树是否是完全二叉树 一个特殊的性质: 1.相同的树 题目链接:力扣(LeetC…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
