App Tracking Transparency Permission with Xamarin Forms iOS

Table of Contents

iTunesConnect is not allowing you to submit the app without the AppTrackingTransparency framework implementation. If you have added a tracking framework in your app you can get an error related to User Tracking Usage in iTunes Connect app privacy section.

TIP

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 websites.

The AppTrackingTransparency framework presents an app-tracking authorization request to the user and provides the tracking authorization status.

AppTrackingTransparency  implementation’

For this, you don’t need a nugget package. ATTrackingManager is part of the iOS SDK (in the AppTrackingTransparency namespace), as long as you target iOS14.5 as a compilation target you will have access to it. The Xamarin.iOS bits are built-in VisualStudio, so just make sure your version is high enough.

Add NSUserTrackingUsageDescription  in info.plist

This is a message that informs the user why an app is requesting permission to use data for tracking the user or the device.

If your app calls the App Tracking Transparency API, you must provide custom text, known as a usage-description string, which displays as a system-permission alert request. The usage-description string tells the user why the app is requesting permission to use data for tracking the user or the device.

Set the NSUserTrackingUsageDescription key in the Information Property List (Info.plist):

  1. Select your project’s Info.plist file in your Xamarin.iOS project.
  2. Modify the file using the Generic PList Editor

3. Add your message with the key NSUserTrackingUsageDescription.

TIP 

Use sentence-style capitalization and appropriate ending punctuation. Keep the text short and specific. You don’t need to include your app name because the system already identifies your app.

Present the app-tracking authorization request to the end user

To request user authorization to access app-related data add in your shared project:

...
public interface IAppTrackingTransparencyPermission
{
        /// <summary>
        /// This method checks if current status of the permission
        /// </summary>
        /// <returns></returns>
        Task<PermissionStatus> CheckStatusAsync();

        /// <summary>
        /// Requests the user to accept or deny a permission
        /// </summary>
        /// <returns></returns>
        void RequestAsync(Action<PermissionStatus> completion);
}
...

In your Xamarin.iOS project adds:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Essentials;
using XEssentialsTest.Extensions;
using static Xamarin.Essentials.Permissions;

namespace AppTrackingTransparency.iOS
{
    public class AppTrackingTransparencyPermission : BasePlatformPermission, IAppTrackingTransparencyPermission
    {
        protected override Func<IEnumerable<string>> RequiredInfoPlistKeys => () =>  new string[] { "NSUserTrackingUsageDescription" };

        // Requests the user to accept or deny a permission
        public void RequestAsync(Action<PermissionStatus> completion)
        {
            ATTrackingManager.RequestTrackingAuthorization((result) => completion(Convert(result)));
        }

        // This method checks if current status of the permission
        public override Task<PermissionStatus> CheckStatusAsync()
        {
            return Task.FromResult(Convert(ATTrackingManager.TrackingAuthorizationStatus));
        }

        private PermissionStatus Convert(ATTrackingManagerAuthorizationStatus status)
        {
            switch (status)
            {
                case ATTrackingManagerAuthorizationStatus.NotDetermined:
                    return PermissionStatus.Disabled;
                case ATTrackingManagerAuthorizationStatus.Restricted:
                    return PermissionStatus.Restricted;
                case ATTrackingManagerAuthorizationStatus.Denied:
                    return PermissionStatus.Denied;
                case ATTrackingManagerAuthorizationStatus.Authorized:
                    return PermissionStatus.Granted;
                default:
                    return PermissionStatus.Unknown;
            }
        }

       
    }
}
...
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
       global::Xamarin.Forms.Forms.Init();

       DependencyService.Register<IAppTrackingTransparencyPermission, AppTrackingTransparencyPermission>();
       LoadApplication(new App());

      return base.FinishedLaunching(app, options);
}
...

In order to use this implementation in your share project you can use it something like this:

...
        protected override async void OnStart()
        {
            if(DeviceInfo.Platform == DevicePlatform.iOS)
            {
                var appTrackingTransparencyPermission = DependencyService.Get<IAppTrackingTransparencyPermission>();
                var status = await appTrackingTransparencyPermission.CheckStatusAsync();

                if (status != PermissionStatus.Granted)                
                    appTrackingTransparencyPermission.RequestAsync(s => MyImplementation(s));
                else
                    MyImplementation(status);                                           
            }
        }

        private void MyImplementation(PermissionStatus status)
        {
            if (status == PermissionStatus.Granted)
            {
                // app center or other implementations
            }
        }
...

Depending on why you are required to show the popup you probably don’t even need to do anything with the result.

Conclusion
My guess is most people will request this permission to comply with an advertising SDK or a Facebook SDK or a social login SDK. Regardless of the user authorizes tracking or not should be transparent to the developer, the SDK will keep working.

When requesting permission is up to you, you can do it as early as possible or wait for a little until the user is engaged with the app and sees value in the tracking. Just know that while the authorization is undefined, the permission will be zeros just as if the permission was denied.

You can see the example source code here.

Share this content!

Facebook
Twitter
LinkedIn
Telegram
WhatsApp