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…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献
Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译: ### 胃肠道癌症的发病率呈上升趋势,且有年轻化倾向(Bray等人,2018&#x…...
