【问题标题】:How to add the AppTrackingTransparency permission to your iOS apps如何将 AppTrackingTransparency 权限添加到您的 iOS 应用程序
【发布时间】:2020-12-14 15:32:44
【问题描述】:

我对 iOS 非常陌生,完全没有 iOS 开发经验,但是,我接到了一个与 preparing for iOS 14+ 相关的任务。根据我发现的https://support.google.com/admanager/answer/9997589,为确保收入没有损失,我需要做两件事。

  1. 为 AdMob 或 Ad Manager 安装最新的 iOS 版 Google 移动广告 SDK(7.64 版或更高版本)
  2. 为您的 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,它会在您启动应用程序本身时显示广告。
  • 当用户接受/拒绝权限时我们是否必须编码?还是操作系统为应用程序做的?例如,如果用户拒绝许可,我们是否必须手动禁用分析?

标签: ios swift permissions ads ios14


【解决方案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 中添加框架

            这可以通过导航到&lt;PROJECT_NAME&gt;.xcproject / &lt;PROJECT_NAME&gt;.xcworkspace -&gt; General -&gt; 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

            1. ATTrackingManagerAuthorizationStatusAuthorized - 同意。
            2. ATTrackingManagerAuthorizationStatusDenied - 拒绝同意。
            3. ATTrackingManagerAuthorizationStatusNotDetermined - 未知同意。
            4. ATTrackingManagerAuthorizationStatusRestricted - 设备应用了 MDM 解决方案。建议在供应商明确提供同意之前,将其与拒绝同意一样处理。

            6。在内部服务器上跟踪用户的同意状态

            如果您要捕获自己的分析,则此步骤是必要的,因为用户可以随时使用 iOS 设置切换同意。

            第三方分析

            推荐

            在同意被拒绝/限制时读取状态值后,在应用启动时从配置中禁用 Firebase AnalyticsFlurry Analytics 或其他分析提供程序会更安全。

            为什么会这样? (在 cmets 中询问):

            1. 即使框架暂时不跟踪用户,SDK 也可能会更新和更改其策略,并且您的代码不会自动同步。
            2. Apple 隐私立法中有很多细微差别,最好避免将商店列入黑名单的风险恕我直言。
            3. 从技术上讲,您可以隐藏 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】:
            1. 打开info.plist文件,添加SKAdNetworkIdentifierNSUserTrackingUsageDescription。以下仅适用于 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>
              
            2. 请求 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...”方法。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-06-30
                  • 2019-09-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-11
                  • 1970-01-01
                  相关资源
                  最近更新 更多