Your complete guide to ATT (updated for iOS 15) 🌈
tl;dr
func applicationDidBecomeActive(_ application: UIApplication) {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
print("enable tracking")
case .denied:
print("disable tracking")
default:
print("disable tracking")
}
}
}
}
Long answer
All new apps submitted to the App Store need to follow App Tracking Transparency guidelines in iOS 14.0+. These guidelines form part of new Apple privacy guidelines. The main idea is for users to be given control of whether all apps can track them, some apps can track them, and make the privacy policies of the apps Transparent on download. :+1: Apple :wink:
1. Add framework in Xcode
This is possible by navigating to <PROJECT_NAME>.xcproject / <PROJECT_NAME>.xcworkspace -> General -> Frameworks, Libraries, and Embedded Content
.
2. Add NSUserTrackingUsageDescription
This is a String key that needs to be added to Info.plist
/ the Xcode project's Information
tab (.xcodeproj or .xcworkspace files).
3. ATTrackingManager.requestTrackingAuthorizationWithCompletionHandler:
This function is advised on the first app launch to ensure the value is captured. The prompt only shows if the app is a fresh install and the user consent status is unknown.
For the majority of applications, only enable tracking if the status is authorized on becoming active (new in iOS 15), as below:
import AppTrackingTransparency
class AppDelegate: UIApplicationDelegate {
func applicationDidBecomeActive(_ application: UIApplication) {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
print("enable tracking")
case .denied:
print("disable tracking")
default:
print("disable tracking")
}
}
}
}
}
NOTE: UI Logic needs to be wrapped on the DispatchQueue.main
queue because the completion block currently executes on a concurrent DispatchQueue
.
4. ATTrackingManager.trackingAuthorizationStatus
Track changes to consent via ATTrackingManager.trackingAuthorizationStatus
which has 4 possible enum values:
ATTrackingManagerAuthorizationStatusAuthorized
- Granted consent.
ATTrackingManagerAuthorizationStatusDenied
- Denied consent.
ATTrackingManagerAuthorizationStatusNotDetermined
- Unknown consent.
ATTrackingManagerAuthorizationStatusRestricted
- Device has an MDM solution applied. Recommend handling this the same as consent denied until vendor provides consent explicitly.
5. Track the user's consent status on internal servers
If you are capturing your own analytics, this step is necessary because the user can toggle consent at any time using iOS Settings.
3rd-Party Analytics
Recommendation
It's safer to disable Firebase Analytics
, Flurry Analytics
, or other Analytics providers from the configuration on app launch after reading the status value when consent is denied/restricted.
Reasoning
- Even if the frameworks don't track users for the moment, the SDKs may update and alter their policies down the line, and your code will not be synced automatically.
- There are lots of nuances in the Apple privacy legislation, and it's better to avoid the risk of getting store blacklisted IMHO.
- Technically you can hide from the Apple privacy guidelines, but do you want to get exposed when they start verifying the accuracy of your App Store statements? This could lead to permanent blacklisting.
To answer your questions:
- No, Analytics will not access the ad ID if no advertising SDKs are present and
AdSupport
is not linked. However, SafariServices
on
iOS 11 imports the AdSupport
framework, causing device advertisement
identifier reporting. #1686 (GH issue #) makes it so that explicit ad
ID access control is required, which is something we need to add on
the Firebase side.
- Yes, if you're using Analytics with an ad framework you should follow Apple's guidelines. You may not be able to submit to the App
Store otherwise.
Other Option
SO, yes it is possible to work around declaring whether you use analytics, but I don’t advise it.
To be honest, I prefer App Store Analytics over 3rd Party Analytics going forward for an integrated experience over more tracking. However, many companies heavily rely on 3rd party analytics data, and if you aren't able to migrate away, transparently declare your analytics usage.
Another ideal strategy would be to fully revamp or rapidly A/B test the app before launching live - use beta modes. Analytics in the App Store is more than enough for live apps.
I can't quantify the risk for being blacklisted subsequently though, as this is library-specific and also depends on your release workflow (do you check for changes in SDK policies?).
Important Note
Wrap
if #available(iOS 14.0, *)
Wherever you call the ATTrackingManager
because the request will not complete on older iOS versions 😅. Track consent on older iOS versions with your own backend flags, or locally on the device.
Apple suggests implementing the new ATT requirements as soon as possible if you track users because you will be blocked from new updates to the App Store in the meantime, even with production crashes. Not only will your users be happier, but your App Store ranking improves if you update your app regularly.
Want to toggle user consent in the app? See here for more info.