iOS Tracking Transparency

You must use the AppTrackingTransparency framework if your app collects data about end users and shares it with other companies for purposes of tracking across apps and web sites (https://developer.apple.com/documentation/apptrackingtransparency).

In this post we’ll see how implement what iOS require for the tracking and i’ll use this example also to explain other concepts.

Let’s start from the end, we want this:

Swift with Storyboard

Create a iOS project using a storyboard:

After that, we add a WebView to the storyboard and apply the constrains to have the webview in full-screen. We must add a string value for the “Privacy – Tracking Description usage” in the info tab. This message have to explain because the user is tracked.

First add an outlet for the webview:

import UIKit
import WebKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

We have to add the import for the Tracking API in the SceneDelegate.swift:

import AdSupport
import AppTrackingTransparency

Now add the code to show the dialog.

struct RequestManager {
    static func getIDFA() -> String {
        return ASIdentifierManager.shared().advertisingIdentifier.uuidString
    }
    
    static func checkTrackingStatus(completionHandler: @escaping (ATTrackingManager.AuthorizationStatus) -> Void) {
        ATTrackingManager.requestTrackingAuthorization { status in
            DispatchQueue.main.async {
                completionHandler(status)
                
            }
        }
    }
}

We create a struct RequestManager, it has two static function, the getIDFA return the Identifier For Advertisers, an UUID used to track the device.

The function checkTrackingStatus is a static function (because is defined in a struct, see https://holyswift.app/the-difference-between-class-func-and-static-func-in-swift-and-why-polymorphism-matters for long explaination) that show (in async way) the dialog to get the permission from the user.

See what’s change in the SceneDelegate:

func sceneDidBecomeActive(_ scene: UIScene) {
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
        attRequest()
    }

func attRequest() {
        RequestManager.checkTrackingStatus { status in
            switch status {
            case .authorized:
                print("Authorized")
            case .denied:
                print("Denied")
            case .notDetermined:
                print("NotDetermined")
                self.attRequest()
            case .restricted:
                print("Restricted")
            @unknown default:
                break
            }
        }
    }

In the sceneDidBecomeActive call the our function attRequest; this function call checkTrackingStatus with a closure, this function gets the status, if the status is notDetermined, the function call itself to re-ask the authorization. Note that we get also the IDFA but in our case we don’t use it.

The code https://github.com/niqt/ShowWebsite

In SwiftUI

How have this using SwiftUI? More simple, add always the string in the plist.info to request the permission and in the code write:

import SwiftUI
import AdSupport
import AppTrackingTransparency

struct ContentView: View {
    var body: some View {
            VStack {
                Text("Got the permission!")
            }.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) {  _ in
                ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                    switch status {
                    case .authorized:
                        print("A")
                    case .denied:
                        print("D")
                    case .notDetermined:
                        print("E")
                    case .restricted:
                        print(" restricted")
                    @unknown default:
                        break
                    }
                    
                })
            }
        }
}

In this case the view require the tracking authorization calling the ATTrackingManager in the onReceive of the VStack (just for example). That’s all.

Note: English is not my native language, so I’m sorry for some errors. I appreciate it if you correct me.

share this post with friends

Picture of Nicola De filippo

Nicola De filippo

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve

Leave a comment

Your email address will not be published. Required fields are marked *

Who I am

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve.

Follow Me Here

Get The Latest Updates

Periodically receive my super contents on coding and programming

join the family;)

Recent Posts