How to add a privacy manifest file to your app for required reason API usage?
Published on: May 1, 2024Apple has recently introduced a new requirement that makes it so that apps that use certain APIs for Apple's mobile platforms (iOS, iPadOS, tvOS, watchOS) must declare their intended use of certain APIs. This requirement has gone in effect on May 1st which means that any app updates or submissions that don't meet Apple's new requirements will be rejected with a "Missing API Declaration" message also referenced as ITMS-91053.
In this post, I'd like to show you how you can add a privacy manifest file to your app so that you can resolve rejections related to ITMS-91053.
We'll go over the following topics:
- Which APIs require a declaration in a privacy manifest?
- How do I add a privacy manifest to my project?
- What about third party SDKs and app extensions?
Let's dive right in, shall we?
The easiest way for you to build your privacy manifest is through my Privacy Manifest Generator. Use it alongside this article to effortlessly get your manifest in order.
If you prefer to learn from videos, watch the video below:
Which APIs require a declaration in a privacy manifest?
Starting May 1st 2024, there's a large list of APIs that require a declaration in your privacy manifest file. For a full overview, you should take a look at Apple's documentation since the list is simply too long for me to repeat here.
Generally speaking though, if you use an API from one of the following categories you almost certainly will need to add a declaration to your privacy manifest:
- File timestamp APIs
- System boot time APIs
- Disk space APIs
- Active keyboard APIs
- User Defaults APIs
Based on this list, I think it's highly likely that you'll be adding a privacy manifest to your app even if you're running a small and simple app because a lot of apps use UserDefaults
to store some basic user information.
For the purposes of this post, I'll show you how you can add an appropriate declaration to your privacy manifest for UserDefaults
. The steps are pretty much the same for every API, they just have different keys that you're supposed to use.
How do I add a privacy manifest file to my project
You can add your privacy manifest just like you add any other file to your project. In Xcode, select file->new->file and look for the privacy manifest file type:
With the privacy manifest file type selected, click next to add your privacy manifest to your app target. It doesn't select your target by default so don't skip doing this yourself. You should keep the default name that Xcode chose for you; PrivacyInfo.
Now that you have your privacy manifest added to your app, it's time to add the correct contents to it.
The first step in the process of figuring out which keys you need to add is to go to Apple's requirements page to find the reference codes that best apply to your usage of required reason APIs:
In the case of UserDefaults
, we're probably interested in one of two keys: CA92.1
or 1C8F.1
depending on whether you're building an app that uses an App Group. Make sure you read every description carefully to ensure you're not missing any small details or nuances in the descriptions; they can be prety hard to read sometimes.
My app isn't part of an App Group so I'll need to declare CA92.1
in my privacy manifest file.
First, I'll need to add the Privacy Accessed API Types
key to my privacy manifest file. Do this by clicking the little + icon next to the App Privacy Configuration key that's already in the privacy manifest. The type of Privacy Accessed API Types
should be an array
.
Next, add a new item to your Privacy Accessed API Types
array. The type of this new item should be a dictionary and in the case of accessing UserDefaults
, you'll need to add a key of Privacy Accessed API Type
with the valueNSPrivacyAccessedAPICategoryUserDefaults
to this dictionary first. The second key you add to your dictionary is Privacy Accessed API Reasons
which is an array. To that array, you add the code for your access reason. In our case that's CA92.1
.
It's pretty tough to correctly describe this plist so let's just go ahead and look at an example:
Note that I only pasted CA92.1
into my privacy manifest as my value for the access reason and Xcode expanded that into the text you see in the screenshot. I personally find it easier to look at the raw XML for this file so if you right click it and select open as you can view the XML source code:
Here's what the source code for my privacy manifest looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
Repeat the steps above for any other required reason APIs you access. If you forget any, Apple will email you with information on which keys you forgot in your rejection email which will help you figure out what to add if you're missing anything.
What about third party SDKs and app extensions?
Every binary in your app must declare its own privacy manifest. So if you have app extensions they must declare required API usage seperately; you can't put all declarations in a single file in your app target.
Your app extensions can use the same files, but they still need to have the file added to their targets explicitly to have them correctly be discoverd.
Third party SDKs must also include a privacy manifest explicitly so if you work on an SDK, now is the time to really make sure you have this done.
In Summary
Adding a privacy manifest file is a new requirement from Apple that, in my opinion, could have been handled better. Manually working on plist files is a tedious job and the keys and values aren't that easy to manage.
Hopefully this post will help you get your app covered for this new requirement so that you can avoid nasty surprises when you submit your app for review!