IDFA iOS14 returns 拒绝显示身份验证弹出窗口
IDFA iOS14 returns denied without displaying auth popup
我正在研究如何在 iOS 14 上获取 IDFA。我正在使用 iPhone 8 Plus。
我已经添加了
<key>NSUserTrackingUsageDescription</key>
<string>App would like to access IDFA for tracking purpose</string>
在 .plist
文件中。
然后添加
let type = ATTrackingManager.trackingAuthorizationStatus;
其中returns.denied
,有
func requestPermission() {
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")
}
}
}
但是我 .denied
没有任何弹出窗口。
你知道这是怎么回事吗?
在系统的设置应用程序中有一个选项“允许应用程序请求跟踪”,如果关闭,requestTrackingAuthorization
将return .denied
立即。
我这边的愚蠢问题,你真的在调用函数吗?
请记住,一旦回答,它就不会再出现。
您必须删除并安装应用程序才能再次显示它
因为用户拒绝了权限
您可以通过我的代码将用户移动到应用程序的设置页面
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
看来你需要使用 iOS 14.4.
我假设你之前设置过一次允许/拒绝。我遇到了同样的问题,即使在我使用 iOS 14.0 尝试卸载应用程序时,请求权限警报也再也不会出现。
但是当我使用 iOS 到 14.4 时,我可以重置设置并通过卸载我的应用程序再次看到询问警报。
如果全局设置允许应用程序请求跟踪关闭,requestTrackingAuthorization
将立即return.denied
。
但对于某些用户,即使在 允许应用程序请求跟踪 开启后,requestTrackingAuthorization
returning .denied
。
这是 OS 问题,已在 14.5.1 版本中修复,因此只需更新您的 OS 即可获取 ATT 对话框。
iOS 和 iPadOS 14.5.1
的发行说明
This update fixes an issue with App Tracking Transparency where some
users who previously disabled Allow Apps to Request to Track in
Settings may not receive prompts from apps after re-enabling it. This
update also provides important security updates and is recommended for
all users.
在 iOS 15 中,仅当应用程序状态已经处于活动状态时,才可以使用 ATTrackingManager.requestTrackingAuthorization 请求它,因此应该从 didFinishLaunchingWithOptions 移动到 applicationDidBecomeActive
SwiftUI iOS 15+
要显示 ATTrackingManager.requestTrackingAuthorization
的警报,您必须确保在应用程序处于活动状态时调用它(否则不会显示警报)
为此,我使用 Publisher 进行检查
ContentView()
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
if ATTrackingManager.trackingAuthorizationStatus == .notDetermined {
ATTrackingManager.requestTrackingAuthorization { status in
//Whether or not user has opted in initialize GADMobileAds here it will handle the rest
GADMobileAds.sharedInstance().start(completionHandler: nil)
}
} else {
GADMobileAds.sharedInstance().start(completionHandler: nil)
}
授权方法ATTrackingManager.requestTrackingAuthorization的调用必须放在主控制器的viewDidAppear(_:)方法中甚至更远(运行之后),即可以绑定到一个按钮
我在隐藏推送通知权限对话框 (completionHandler) 后立即请求跟踪权限。它总是返回被拒绝,奇怪的是增加一秒的延迟为我修复了它。
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
// Your dialog
}
您需要将您的代码移动到 AppDelegate,并且 运行 在应用程序激活时将其移动,如 @Serg Smyk 所说。
func applicationDidBecomeActive(_ application: UIApplication) {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
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")
}
}
}
}
在 SwiftUI 中:
添加一个属性捕捉ScenePhase,然后:
@Environment(\.scenePhase) var scenePhase
struct ContentView: View {
@Environment(\.scenePhase) var scenePhase
var body: some View {
Text("Hello, world!")
.padding()
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
print("Active")
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
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")
}
}
}
} else if newPhase == .inactive {
print("Inactive")
} else if newPhase == .background {
print("Background")
}
}
}
}
我正在研究如何在 iOS 14 上获取 IDFA。我正在使用 iPhone 8 Plus。
我已经添加了
<key>NSUserTrackingUsageDescription</key>
<string>App would like to access IDFA for tracking purpose</string>
在 .plist
文件中。
然后添加
let type = ATTrackingManager.trackingAuthorizationStatus;
其中returns.denied
,有
func requestPermission() {
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")
}
}
}
但是我 .denied
没有任何弹出窗口。
你知道这是怎么回事吗?
在系统的设置应用程序中有一个选项“允许应用程序请求跟踪”,如果关闭,requestTrackingAuthorization
将return .denied
立即。
我这边的愚蠢问题,你真的在调用函数吗? 请记住,一旦回答,它就不会再出现。 您必须删除并安装应用程序才能再次显示它
因为用户拒绝了权限
您可以通过我的代码将用户移动到应用程序的设置页面
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
看来你需要使用 iOS 14.4.
我假设你之前设置过一次允许/拒绝。我遇到了同样的问题,即使在我使用 iOS 14.0 尝试卸载应用程序时,请求权限警报也再也不会出现。 但是当我使用 iOS 到 14.4 时,我可以重置设置并通过卸载我的应用程序再次看到询问警报。
如果全局设置允许应用程序请求跟踪关闭,requestTrackingAuthorization
将立即return.denied
。
但对于某些用户,即使在 允许应用程序请求跟踪 开启后,requestTrackingAuthorization
returning .denied
。
这是 OS 问题,已在 14.5.1 版本中修复,因此只需更新您的 OS 即可获取 ATT 对话框。
iOS 和 iPadOS 14.5.1
的发行说明This update fixes an issue with App Tracking Transparency where some users who previously disabled Allow Apps to Request to Track in Settings may not receive prompts from apps after re-enabling it. This update also provides important security updates and is recommended for all users.
在 iOS 15 中,仅当应用程序状态已经处于活动状态时,才可以使用 ATTrackingManager.requestTrackingAuthorization 请求它,因此应该从 didFinishLaunchingWithOptions 移动到 applicationDidBecomeActive
SwiftUI iOS 15+
要显示 ATTrackingManager.requestTrackingAuthorization
的警报,您必须确保在应用程序处于活动状态时调用它(否则不会显示警报)
为此,我使用 Publisher 进行检查
ContentView()
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
if ATTrackingManager.trackingAuthorizationStatus == .notDetermined {
ATTrackingManager.requestTrackingAuthorization { status in
//Whether or not user has opted in initialize GADMobileAds here it will handle the rest
GADMobileAds.sharedInstance().start(completionHandler: nil)
}
} else {
GADMobileAds.sharedInstance().start(completionHandler: nil)
}
授权方法ATTrackingManager.requestTrackingAuthorization的调用必须放在主控制器的viewDidAppear(_:)方法中甚至更远(运行之后),即可以绑定到一个按钮
我在隐藏推送通知权限对话框 (completionHandler) 后立即请求跟踪权限。它总是返回被拒绝,奇怪的是增加一秒的延迟为我修复了它。
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
// Your dialog
}
您需要将您的代码移动到 AppDelegate,并且 运行 在应用程序激活时将其移动,如 @Serg Smyk 所说。
func applicationDidBecomeActive(_ application: UIApplication) {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
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")
}
}
}
}
在 SwiftUI 中:
添加一个属性捕捉ScenePhase,然后:
@Environment(\.scenePhase) var scenePhase
struct ContentView: View {
@Environment(\.scenePhase) var scenePhase
var body: some View {
Text("Hello, world!")
.padding()
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
print("Active")
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
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")
}
}
}
} else if newPhase == .inactive {
print("Inactive")
} else if newPhase == .background {
print("Background")
}
}
}
}