Search code examples
iosxcodeapp-storeapp-store-connect

How do I resolve ITMS-91053: Missing API declaration for NSPrivacyAccessedAPICategoryUserDefaults and declare reasons why my app uses UserDefaults?


I'm getting ready to distribute my first app on the iOS store. My app uses UserDefaults to save a few variables for when the app is relaunched.

I've heard I need to declare the reasons why I'm using UserDefaults, but I'm unable to figure out where I should do so. On App Store Connect, UserDefaults isn't listed under Capabilities. I assume this might be in a plist on Xcode's Build Settings, but I'm completely lost. Any suggestions?

Edit 01: This is where I heard I need to declare a reason (last paragraph): https://www.hackingwithswift.com/books/ios-swiftui/storing-user-settings-with-userdefaults


Solution

  • Start with Apple's documentation for Privacy manifest files. You need to create a privacy manifest file.

    To add the privacy manifest to your app in Xcode, choose File > New File, and scroll down to the Resource section. Select the App Privacy file type, click Next, then click Create. By default, the file is named PrivacyInfo.xcprivacy; don’t change the filename. At the top level of this property list file, add the following keys to the dictionary.

    For the UserDefaults privacy reasons, you need the key NSPrivacyAccessedAPITypes. This is described in the above documentation as:

    An array of dictionaries that describe the API types your app or third-party SDK accesses that have been designated as APIs that require reasons to access. For information on the keys and values to use in the dictionaries, see Describing use of required reason API.

    The UserDefaults specific section can be found here.

    The following shows a minimal example for indicating that you only use app-specific values in UserDefaults:

    enter image description here

    The corresponding XML of this plist looks as follows:

    <?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>NSPrivacyAccessedAPITypeReasons</key>
                <array>
                    <string>CA92.1</string>
                </array>
                <key>NSPrivacyAccessedAPIType</key>
                <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
            </dict>
        </array>
    </dict>
    </plist>
    

    It's much easier to create this in Xcode as a plist and not as XML since Xcode lets you select only the relevant keys and values.

    My example shows the UserDefaults reason as CA92.1. You must of course provide the value(s) appropriate for your app.

    My example also only shows a bare minimum just for the UserDefaults API. See the linked documentation for other top-level keys you also need as well as other APIs your app may need to provide.