问题描述
我对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
中?还是真的只是某个适合代码库的地方?谢谢。
解决方法
如果用户没有向应用授予跟踪权限会怎样?那么当用户不允许跟踪权限时,您将无法获得 IDFA,那么您的收入将再次下降...有关更多信息,请参阅 Answer
为了解决这个问题,Google 移动广告 SDK 支持使用 Apple 的 SKAdNetwork 进行转化跟踪,即使 IDFA 不可用,Google 也可以将应用安装归因。
面向广告商的 SKAdNetwork 解决方案,为 Apple 的 SKAdNetwork 提供开箱即用的支持,并最大限度地提高您未来在 iOS 14 及更高版本上的增长。
要解决此问题,请启用 SKAdNetwork 以跟踪转化
Google 移动广告 SDK 支持使用 Apple 的 SKAdNetwork 进行转化跟踪,即使 IDFA 不可用,Google 也可以将应用安装归因。
要启用此功能,请使用附加字典更新 SKAdNetworkItems
键,该字典定义了 Info.plist 中 Google 的 SKAdNetworkIdentifier
值。
<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>
,
对于那些可能会遇到相同问题的人,我看到了带有功能的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
,我们正在使用 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 令牌,我们没有将它们包含在保护之后,也没有问题。
,根据您发布的链接:
https://developers.google.com/admob/ios/ios14#swift。
避免 AdMob 收入损失的主要方式是将其添加到 Info.plist 中:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin
我不知道何时/是否需要 AppTrackingTransparency 权限。我知道苹果说你需要它,但他们没有给出最后期限。 Google 说“如果您决定包含 App Tracking Transparency”,这对我来说是暗示不要打扰!
,还有其他事情,Apple已通过“允许应用程序请求跟踪”添加了新的隐私设置“跟踪”。如果禁用此选项,iOS将忽略所有权限屏幕请求。
您可以在article here
中查看更多详细信息 ,作为对@mark 答案的补充,您还应该在关键隐私 - 跟踪使用说明中的 plist 文件中添加权限声明
,根据 iOS 14.0+ 中的 App Tracking Transparency 提交到 App Store 的所有新应用现在都需要这样做。
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 只返回两个值,分别映射到 grant 或 denied:
ATTrackingManagerAuthorizationStatusAuthorized
表示授权同意跟踪的用户。
ATTrackingManagerAuthorizationStatusDenied
表示用户拒绝同意跟踪。
注意:UI 逻辑需要包装在 DispatchQueue.main
队列中,因为完成块当前在并发 DispatchQueue
上执行。
5. ATTrackingManager.trackingAuthorizationStatus
通过具有 4 possible enum values 的 ATTrackingManager.trackingAuthorizationStatus
跟踪同意更改:
ATTrackingManagerAuthorizationStatusAuthorized
ATTrackingManagerAuthorizationStatusDenied
ATTrackingManagerAuthorizationStatusNotDetermined
ATTrackingManagerAuthorizationStatusRestricted
6.在内部服务器上跟踪用户的同意状态
如果您要捕获自己的分析,则此步骤是必要的,因为用户可以随时使用 iOS 设置切换同意。我们还需要在拒绝同意时读取状态值后,在应用启动时从配置中禁用 Firebase Analytics
、Flurry Analytics
或其他分析提供程序。
重要提示
包裹
if #available(iOS 14.0,*)
无论您在哪里调用 ATTrackingManager
,因为该请求将无法在较旧的 iOS 版本上完成?。使用您自己的后端标志或在设备本地跟踪旧版 iOS 上的同意情况。
如果您跟踪用户,Apple 建议尽快实施新的 ATT 要求,因为在此期间您将无法获得 App Store 的新更新,即使生产崩溃也是如此。如果您定期更新您的应用,不仅您的用户会更开心,而且您的 App Store 排名也会提高。
想要在应用中切换用户同意吗?有关详细信息,请参阅 here。
,-
打开
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]; }