How to implement App Tracking Transparency in Swift?
App Tracking Transparency is a must for iOS apps with access to websites. Learn how to implement it in your Swift project from this article!
Table of content
Since WWDC20, Apple requires extra information about tracking users’ activity.
It is not only about tracking them inside apps but also in cases when an app uses access to websites. It means, if in-app WebKit is implemented, there should be added extra policy about tracking.
If your app offers access to websites, you have to implement App Tracking Transparency. In this tutorial, I’ll show you how to do this and how to avoid common mistakes.
What is App Tracking Transparency?
Implementing App Tracking Transparency can be a real pain in the neck.
Although Apple provides documentation about their requirements, in my opinion, these requirements are not well-explained. Therefore you may encounter difficulties trying to explain, what kind of tracking is implemented on websites that are embedded in apps.
Before accessing a website, a user has to consent to be tracked.
Alongside the Info.plist file you have to add information about the purpose of user tracking. So firstly we need to go to the Info.plist file in an Xcode project. Then we need to add:
NSUserTrackingUsageDescription
It should contain information, why we need to track a user on the websites our application has access to, e.g.:
- This app needs permission to track you across apps and websites owned by 3rd parties. This identifier will be used to collect cookies about your internet activity.
Be sure that you’ve typed exactly what kind of information your website will collect. Apple is very strict on this topic and your app may be rejected during the review if the explanation is too general.
Request tracking in an app
Adding explanation info key to Info.plist was but the first step.
Having done this, we need to add a special alert. So the next step is to request tracking in your app.
It can be done during an app’s launching or its usage. Although it has to be launched before a user gains access to websites via your app. Otherwise, Apple won’t agree to release your app on AppStore.
So we need to use the following method:
class func requestTrackingAuthorization(completionHandler completion: @escaping (ATTrackingManager.AuthorizationStatus) -> Void)
This method returns authorization status which contains the following options:
ATTrackingManager.AuthorizationStatus.authorized,
ATTrackingManager.AuthorizationStatus.denied,
ATTrackingManager.AuthorizationStatus.notDetermined,
ATTrackingManager.AuthorizationStatus.restricted
Only the first status allows opening a website in the app. Otherwise, the app should block such access. Although requestTrackingAuthorization is called only once, the user can always change the tracking status. It can be done via Settings in iOS. Simply, open Settings, then Privacy, and Tracking tab. In this section, your app with the current tracking status should be visible.
Checking the app tracking status
The last thing about implementing App Tracking Transparency is checking if a user didn’t change his or her mind in regards to tracking.
Tracking consent can be changed via iOS Settings, so launching the WebKit module every time we need to check if tracking consent is granted. This can be done thanks to the method:
class var trackingAuthorizationStatus: ATTrackingManager.AuthorizationStatus { get }
So you can simply return block with Boolean value (trackingAuthorizationStatus == .authorized) to check if a user can open a website in your app. It can look like this:
if ATTrackingManager.trackingAuthorizationStatus == .authorized {
//Open website
}
Don’t forget to import AppTrackingTransparency into your controller. If you want to implement ads in your app, you should also import AdSupport, because App Tracking will be also used for granting access to ads.
Possible problems
What I found during implementing the App Tracking Transparency, were the problems with refreshing content and checking current tracking status.
Let’s say we have a UIViewController with an implemented WKWebView inside.
Whenever we open this view, we need to check if tracking is allowed. Like in the second part of this text (ATTrackingManager.trackingAuthorizationStatus). But checking the status is usually performed alongside the opening of a controller.
We can use DispatchQueue.main.async for handling this. Like this one:
ATTrackingManager.requestTrackingAuthorization { [weak self] status in
if status == .authorized {
DispatchQueue.main.async {
self?.open(url: url)
}
}
}
If we have implemented refreshing inside the app or we just want to check if the controller is properly displayed, we can implement a custom method to check this. Like this one:
func openWebView(url: URL, onShow: @escaping () -> ())
Then in this function we use:
self.present(navigation, animated: true, completion: {
onShow()
})
Of course, we can use UINavigationController to present the new controller.
While checking the authorization status we can also check if the controller with WebKit inside is properly displayed. Now we have checked all possible errors that may occur on implementing App Tracking Transparency inside our app.
I hope that thanks to this tutorial implementing App Tracking Transparency in your iOS apps built with Swift will be easier than before.