如何将 AppTrackingTransparency 权限添加到您的 iOS 应用程序
Posted
技术标签:
【中文标题】如何将 AppTrackingTransparency 权限添加到您的 iOS 应用程序【英文标题】:How to add the AppTrackingTransparency permission to your iOS apps 【发布时间】:2020-12-14 15:32:44 【问题描述】:我对 ios 非常陌生,完全没有 iOS 开发经验,但是,我接到了一个与 preparing for iOS 14+
相关的任务。根据我发现的https://support.google.com/admanager/answer/9997589,为确保收入没有损失,我需要做两件事。
-
为 AdMob 或 Ad Manager 安装最新的 iOS 版 Google 移动广告 SDK(7.64 版或更高版本)
为您的 iOS 应用添加 AppTrackingTransparency 权限。
我遵循了一些指南,并且正在处理将AppTrackingTransparency permission
添加到 iOS 应用程序的问题。这是我正在使用的指南,https://developers.google.com/admob/ios/ios14#swift。
我设法在Info.plist
中添加了如下所示的键/值
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
但这是我希望得到帮助的地方。我认为我仍然需要在某处添加代码以使用 AppTrackingTransparency 请求用户许可。根据指南,我认为显示App Tracking Transparency dialog box
需要以下代码。 Question 1
,我的假设正确吗?
import AppTrackingTransparency
import AdSupport
...
func requestIDFA()
ATTrackingManager.requestTrackingAuthorization(completionHandler: status in
// Tracking authorization completed. Start loading ads here.
// loadAd()
)
Question 2
,代码是否存在于AppDelegate.swift
?或者它真的只是适合代码库中的某个地方吗?谢谢。
【问题讨论】:
1.在 info.plist 中添加密钥后,使用说明会作为 App Tracking Transparency 对话框的一部分出现。无需为此添加任何特殊代码。 2. 您可以将代码添加到您想要在其上显示广告的任何视图控制器。如果您添加 Appdelegate,它会在您启动应用程序本身时显示广告。 当用户接受/拒绝权限时我们是否必须编码?还是操作系统为应用程序做的?例如,如果用户拒绝许可,我们是否必须手动禁用分析? 【参考方案1】:对于那些可能遇到相同问题的人,我让 AppTrackingTransparency 对话框与该功能一起出现,
import AppTrackingTransparency
import AdSupport
//NEWLY ADDED PERMISSIONS FOR iOS 14
func requestPermission()
if #available(iOS 14, *)
ATTrackingManager.requestTrackingAuthorization status in
switch status
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
// Now that we are authorized we can get the IDFA
print(ASIdentifierManager.shared().advertisingIdentifier)
case .denied:
// Tracking authorization dialog was
// shown and permission is denied
print("Denied")
case .notDetermined:
// Tracking authorization dialog has not been shown
print("Not Determined")
case .restricted:
print("Restricted")
@unknown default:
print("Unknown")
//
然后,我在应用程序的登录页面上简单地调用了函数requestPermission()
,因此用户在登录之前会看到权限对话框。如果不调用该函数,本指南中显示的对话框https://developers.google.com/admob/ios/ios14不会出现我。
本文有一个示例github项目:https://medium.com/@nish.bhasin/how-to-get-idfa-in-ios14-54f7ea02aa42
【讨论】:
【参考方案2】:作为@mark 答案的补充,您还应该在关键隐私-跟踪使用说明中的 plist 文件中添加权限声明
【讨论】:
【参考方案3】:根据您发布的链接:
https://developers.google.com/admob/ios/ios14#swift.
避免 AdMob 收入损失的主要方法是将其添加到 Info.plist 中:
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
我不知道何时/是否需要 AppTrackingTransparency 权限。我知道苹果说你需要它,但他们没有给出最后期限。 Google 说“如果您决定加入 App Tracking Transparency”,这对我来说是在暗示不要打扰!
【讨论】:
【参考方案4】:如果用户不授予应用跟踪权限会怎样?那么当用户不允许跟踪权限时,您将无法获得 IDFA 那么您的收入将再次下降...更多请参阅Answer
为了解决这个问题,Google 移动广告 SDK 支持使用 Apple 的 SKAdNetwork 进行转化跟踪,即使 IDFA 不可用,Google 也可以将应用安装归因。
面向广告商的 SKAdNetwork 解决方案可让您获得对 Apple SKAdNetwork 的开箱即用支持,并在 iOS 14 及更高版本上最大限度地提高您的未来增长。
要解决此问题,请启用 SKAdNetwork 来跟踪转化
Google 移动广告 SDK 支持使用 Apple 的 SKAdNetwork 进行转化跟踪,即使 IDFA 不可用,Google 也可以将应用安装归因。
要启用此功能,请使用在 Info.plist 中定义 Google 的 SKAdNetworkIdentifier
值的附加字典更新 SKAdNetworkItems
键。
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>4fzdc2evr5.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>2fnua5tdw4.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>ydx93a7ass.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>5a6flpkh64.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>p78axxw29g.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>v72qych5uu.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>c6k4g5qg8m.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>s39g8k73mm.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>3qy4746246.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>3sh42y64q3.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>f38h382jlk.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>hs6bdukanm.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>prcb7njmu6.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>wzmmz9fp6w.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>yclnxrl5pm.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>4468km3ulz.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>t38b2kh725.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>7ug5zh24hu.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>9rd848q2bz.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>n6fk4nfna4.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>kbd757ywx3.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>9t245vhmpl.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>2u9pt9hc89.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>8s468mfl3y.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>av6w8kgt66.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>klf5c3l5u5.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>ppxm28t8ap.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>424m5254lk.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>uw77j35x4d.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>e5fvkxwrpn.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>zq492l623r.skadnetwork</string>
</dict>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>3qcr597p9d.skadnetwork</string>
</dict>
</array>
【讨论】:
【参考方案5】:我们正在使用 Firebase 和 Facebook,为了让应用获得批准,我们将这两个调用都放在 ATT 保护“后面”,即:
对于 Facebook(来自 AppDelegate):
if #available(iOS 14, *)
ATTrackingManager.requestTrackingAuthorization status in
if status == .authorized
ApplicationDelegate.shared.application(
application,
didFinishLaunchingWithOptions: launchOptions
)
对于 Firebase:
if #available(iOS 14, *)
ATTrackingManager.requestTrackingAuthorization status in
if status == .authorized
Analytics.logEvent(eventName, parameters: [:])
至于通知的 firebase 令牌,我们没有将它们包含在保护之后并且没有问题。
【讨论】:
【参考方案6】:ATT 的步骤和注意事项
所有提交到 App Store 的新应用程序都需要遵循 iOS 14.0+ 中的App Tracking Transparency 准则。这些指南是新Apple privacy guidelines 的一部分。主要思想是让用户控制是否所有应用都可以跟踪它们,某些应用可以跟踪它们,并使应用的隐私政策在下载时透明。 :+1: 苹果 :wink:
1。在 Xcode 中添加框架
这可以通过导航到<PROJECT_NAME>.xcproject / <PROJECT_NAME>.xcworkspace -> General -> Frameworks, Libraries, and Embedded Content
来实现。
2。加NSUserTrackingUsageDescription
这是一个字符串键,需要添加到Info.plist
。
3。 import AppTrackingTransparency
适当
4。 ATTrackingManager.requestTrackingAuthorizationWithCompletionHandler:
建议在首次启动应用时使用此功能,以确保捕获该值。该提示仅在应用是全新安装且用户同意状态未知时显示。
Apple 只返回两个值,分别对应于授权或拒绝:
ATTrackingManagerAuthorizationStatusAuthorized
表示授权同意跟踪的用户。
ATTrackingManagerAuthorizationStatusDenied
表示用户拒绝同意跟踪。
注意:UI Logic 需要包装在 DispatchQueue.main
队列中,因为完成块当前在并发 DispatchQueue
上执行。
5。 ATTrackingManager.trackingAuthorizationStatus
通过ATTrackingManager.trackingAuthorizationStatus
跟踪同意更改,4 possible enum values:
ATTrackingManagerAuthorizationStatusAuthorized
- 同意。
ATTrackingManagerAuthorizationStatusDenied
- 拒绝同意。
ATTrackingManagerAuthorizationStatusNotDetermined
- 未知同意。
ATTrackingManagerAuthorizationStatusRestricted
- 设备应用了 MDM 解决方案。建议在供应商明确提供同意之前,将其与拒绝同意一样处理。
6。在内部服务器上跟踪用户的同意状态
如果您要捕获自己的分析,则此步骤是必要的,因为用户可以随时使用 iOS 设置切换同意。
第三方分析
推荐
在同意被拒绝/限制时读取状态值后,在应用启动时从配置中禁用 Firebase Analytics
、Flurry Analytics
或其他分析提供程序会更安全。
为什么会这样? (在 cmets 中询问):
-
即使框架暂时不跟踪用户,SDK 也可能会更新和更改其策略,并且您的代码不会自动同步。
Apple 隐私立法中有很多细微差别,最好避免将商店列入黑名单的风险恕我直言。
从技术上讲,您可以隐藏 Apple privacy guidelines,但您是否希望在他们开始 verifying the accuracy 您的 App Store 声明时暴露?这可能会导致永久列入黑名单。
例如Firebase policy (26.06.20)
回答您的问题:
不,如果不存在广告 SDK 且未链接AdSupport
,Analytics 将不会访问广告 ID。但是,SafariServices
on iOS 11 导入AdSupport
框架,导致设备广告 标识符报告。第1686章(GH问题#)让露骨广告 需要ID访问控制,这是我们需要添加的 Firebase 方面。 是的,如果您将 Analytics 与广告框架一起使用,则应遵循 Apple 的指南。您可能无法提交到应用程序 以其他方式存放。
其他选项
所以,是的可以解决(例如避税)声明您是否使用分析。如果您的公众形象在 App Store 上对您很重要,这可能是值得的。
但是,老实说,我可能会移除 3rd Party Analytics 并继续使用 App Store Analytics 以获得更好的体验(如果可能的话)。这样您就可以安全地维护您的公众形象。
另一个理想的策略是在启动实时使用 beta 模式之前对应用进行全面改造或快速 A/B 测试。 App Store 中的分析对于实时应用来说绰绰有余。
但我无法量化随后被列入黑名单的风险,因为这是特定于库的,并且还取决于您的发布工作流程(您是否检查 SDK 政策的变化?)。
重要提示
包装
if #available(iOS 14.0, *)
无论您在哪里调用ATTrackingManager
,因为该请求不会在较旧的 iOS 版本上完成?。使用您自己的后端标志或在本地设备上跟踪旧 iOS 版本的同意情况。
如果您跟踪用户,Apple 建议尽快实施新的 ATT 要求,因为在此期间您将被阻止对 App Store 进行新的更新,即使生产崩溃也是如此。如果您定期更新您的应用,您的用户不仅会更快乐,而且您的 App Store 排名也会提高。
想要在应用中切换用户同意?请参阅here 了解更多信息。
【讨论】:
你知道TrackingAuthorizationStatus什么时候会被“限制”吗? “限制”和“拒绝”有什么区别? 我认为“restricted”应该和“denied”一样对待。我相信受限设备应用了 MDM 解决方案,因此该设备不会征求同意 - 更多详情 here。 如果跟踪被拒绝,我认为您不需要关闭 FirebaseAnalytics。此跟踪用于链接用户跨应用程序和网络浏览的在线活动,以便能够识别他并提供有针对性的广告。 FirebaseAnalytics 与此无关。仅当您专门跟踪他的活动,例如“searched_nike_shoes_size_42”并分配一个 ID,然后将此数据出售给 DataBroker。 @Starsky不一定,看看Google’s官方回复。【参考方案7】:打开info.plist
文件,添加SKAdNetworkIdentifier
和NSUserTrackingUsageDescription
。以下仅适用于 Google (Admob),您可以找到完整列表here。
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
//..
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
请求 ATT 对话框。 (为简单起见,我在应用加载后立即请求)
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
//...
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// ...
if (@available(iOS 14.0, *))
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status)
// Tracking authorization completed. Start loading ads here.
// [self loadAd];
];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
【讨论】:
【参考方案8】:在 iOS 15 中,如果应用程序状态已处于活动状态,则只能使用 ATTrackingManager.requestTrackingAuthorization
请求,因此应将其从 didFinishLaunchingWithOptions
移动到 applicationDidBecomeActive
。
【讨论】:
【参考方案9】:我观察到如果以下方法
“ATTrackingManager requestTrackingAuthorizationWithCompletionHandler()”
从 AppDelegate 调用,然后有时会返回“ATTrackingManagerAuthorizationStatusNotDetermined”作为状态并且不显示警报。 我手机的iOS版本是“iOS-15.0.2”
作为一种解决方案,我们可以在闪屏后或出现LandingPage后调用“requestTrackingAuthorization...”方法。
【讨论】:
以上是关于如何将 AppTrackingTransparency 权限添加到您的 iOS 应用程序的主要内容,如果未能解决你的问题,请参考以下文章