ITMS-91053: Missing API declaration

when upload appconnect:

Although submission for TestFlight review was successful, you may want to correct the following issues in your next submission for TestFlight review. Once you’ve corrected the issues, upload a new binary to App Store Connect.
ITMS-91053: Missing API declaration - Your app’s code in the “” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryDiskSpace. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: Describing use of required reason API | Apple Developer Documentation.

I’m getting the same thing when submitting to TestFlight. It looks like a new requirement that Apple just added. Googling it I’ve found some info on creating the needed Privacy file in Xcode or manually.

so it seems fairly simple to create the file.
But what i don’t know, is how to get Unreal to include the Privacy file when it builds the App.
Maybe we just stick it in the config folder?

-e

Edit: Although this solution does work, I suggest following the instructions from @NiizOP or @Trout_Zhang further down the thread.

We’ve recently hit this particular problem as well.

We use a somewhat custom build system, so I can’t guarantee this will be the whole set of steps you’ll need, but this is what we did to get a PrivacyInfo.xcprivacy file into our ipa. Be aware that we had to make engine changes to achieve this, so if you’re not building from source you’ll have to unfortunately wait until there is offical support from Epic.
We are currently using UE4.27+. I don’t know how easily ported this can be to UE5 (or whether it’s required at all).

  1. Firstly in XCode we created a new xcprivacy file with the appropriate entries (check the links by TTF_eric1 above), and saved it to [ProjectName]/Build/IOS
  2. In IOSPlatform.Automation.cs, function GetFilesToDeployOrStage, just after the “// copy the icons from the game (may stomp the engine copies)” block, add the following:
					// Privacy manifest
					DirectoryReference PrivacyDataPath = DirectoryReference.Combine(SC.ProjectRoot, "Build", PlatformName);
					FileReference PrivacyManifestFile = FileReference.Combine(PrivacyDataPath, "PrivacyInfo.xcprivacy");
					if (File.Exists(PrivacyManifestFile.ToNormalizedPath()))
					{
						SC.StageFile(StagedFileType.SystemNonUFS, PrivacyManifestFile, new StagedFileReference("PrivacyInfo.xcprivacy"));
					}

This should stage your Privacy file and package it within your IPA. You can check it has been packaged correctly when your build has finished by checking [ProjectName]/Binaries/IOS/Payload and right clicking the [ProjectName].app and selecting Show Package Conttents, you should see it there in the top level directory alongside your Info.plist etc.

Hope that helps!
Matt

2 Likes

Is there any news from Epic on if this will be supported and added? It seems like this would be pretty critical to have them fix, or at least show how to workaround.

Did you have this resolved? I have the same issue with an app I’m currently developing in Unreal Engine 5.2 I’d hate to have it be impossible to submit new version, but currently I dont know how to add this file when building from the Epic Launcher version of Unreal (not a custom compiled version)

I’ve taken the instructions from Milly01 above and implemented those in UE5.2 and have successfully submitted my app to Test Flight. (I didn’t get a warning email back) So it looks like this works.

The solution is quite simple to implement. You just need to customize and rebuild the Unreal Build Tool (UBT) & Automation Tools. I think it might be possible to pull out the patched Automation & UBT and put them into a Luancher version of UE5.2 as they are seperate apps from the Editor. This would mean that you can use the patched versions without having to build the engine from source which is a pain to do…

My understanding is that Epic has fixed this issue in UE5.4. But it seems unclear if they are going to fix it in earlier versions.

-e

There is no need to rebuild the engine for this. An UPL script can be used to put the PrivacyInfo.xcprivacy file where it is needed and make sure this is done during the Build / Stage / Archive steps.

Here are the steps to achieve it (assuming your project is named “MyProject”):

  1. Put your PrivacyInfo.xcprivacy file in the Build/IOS/ folder.
  2. Add the following UPL script in your Source/MyProject folder, name the file AddPrivacyInfo_IOS_UPL.xml. It must be next to your MyProject.Build.cs file. This script will make sure to copy the PrivacyInfo.xcprivacy from the Build/IOS folder to the final folder used to generate the .ipa file that will be uploaded later to Apple servers:
<?xml version="1.0" encoding="utf-8"?>
<root>
    <init>
        <log text="In need of a PrivacyInfo.xcprivacy? No worries, I got you..."/>
        <!-- PluginDir is the folder where this file is... weird name, but hey, I don't make the rules! -->
        <copyFile src="$S(PluginDir)/../../Build/IOS/PrivacyInfo.xcprivacy" dst="$S(BuildDir)/PrivacyInfo.xcprivacy" />
    </init>
</root>
  1. Edit your Source/MyProject/MyProject.Build.cs file and add the following lines. This will simply add the UPL script to the Build / Stage and Archive steps:
		if (Target.Platform == UnrealTargetPlatform.IOS)
		{
			string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
			AdditionalPropertiesForReceipt.Add("IOSPlugin", System.IO.Path.Combine(PluginPath, "AddPrivacyInfo_IOS_UPL.xml"));
        }
  1. Package, check for the “In need of a PrivacyInfo.xcprivacy? No worries, I got you…” line in the logs and then enjoy seeing the PrivacyInfo.xcprivacy in the final .ipa file.

I am confident this can work for older version of UE, like UE4.27.

2 Likes

Thanks,want to try, no code experience, can you give us more details about how to create UPL_script ( AddPrivacyInfo_IOS_UPL.xml) file in this case?

You just need to copy/paste the XML structure:

AddPrivacyInfo_IOS_UPL.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
    <init>
        <log text="In need of a PrivacyInfo.xcprivacy? No worries, I got you..."/>
        <!-- PluginDir is the folder where this file is... weird name, but hey, I don't make the rules! -->
        <copyFile src="$S(PluginDir)/../../Build/IOS/PrivacyInfo.xcprivacy" dst="$S(BuildDir)/PrivacyInfo.xcprivacy" />
    </init>
</root>

Same case here; we need to prepare a near submission with UE5.2.

Here is my change; it may be simpler than all the above ways. Just add the following to one of your game modules’ (YourGameModule).build.cs

#if !UE_5_3_OR_LATER
		// Adding PrivacyInfo.xcprivacy file, which Apple mandated, to ipa bundle in lower UE5 versions( < UE5.3) that don't support it natively
		if (Target.Platform == UnrealTargetPlatform.IOS)
		{
			AdditionalBundleResources.Add(new BundleResource(Path.Combine(Target.ProjectFile.Directory.ToString(), "Build/IOS/Resources/UEMetadata/PrivacyInfo.xcprivacy")));
		}
#endif

And I agree with @NiizOP that this does not need to be modified at the engine level. As the sole UE engine code maintainer in my team, I always tried to keep changes in the project level as much as possible to make my life easier when upgrading the engine(4.27->5.0, 5.0->5.2, and 5.2->maybe 5.4 later)

1 Like

Essentially, only 1 line

if (Target.Platform == UnrealTargetPlatform.IOS) {AdditionalBundleResources.Add(new BundleResource(Path.Combine(Target.ProjectFile.Directory.ToString(), "Build/IOS/Resources/UEMetadata/PrivacyInfo.xcprivacy")));}
  • Assume you have the PrivacyInfo.xcprivacy file from epic’s engine path like UnrealEngine-5.4.1-release\Engine\Build\IOS\Resources\UEMetadata\PrivacyInfo.xcprivacy and copied to your project under (YourProj)\Build\IOS\Resources\UEMetadata\PrivacyInfo.xcprivacy