Empty Display Name on Xcode

Is it normal that “Display Name” is empty after adding the “iOS App Info” on Localization Settings? It works when the app is deployed to the phone, but it shows empty on Xcode. Thanks.

8088329--1046177--upload_2022-4-29_11-1-56.png

8088329--1046174--upload_2022-4-29_11-1-40.png

Yes from what I can recall the value is in a different info.plist file.

1 Like

Hi, my previous project was showing empty in “Bundle Display Name” from info.plist file and was able to released to App Store.
But now I use the same method for my new project and I get a warning message from Apple

We identified one or more issues with a recent delivery for your app, MY_APP_NAME. Your delivery was successful, but you may wish to correct the following issues in your next delivery:
ITMS-90784: Missing bundle name - The CFBundleName and CFBundleDisplayName Info.plist keys are missing or have empty values in the bundle with MY_BUNDLE_ID bundle ID.

Could you assist me please ?

You will need to manually edit the info.plist file to give it default values. We have fixed this in the next release.

1 Like

Thanks for clarifying.

But I am using Unity Cloud Build, may I know how to add it default values please ?

You can’t. You would need to modify the localization package code.
Move the localization package from the package cache into the projects Packages folder.
Now replace the script Editor/Platform/iOS/Player.cs contents with this:

#if UNITY_IOS || UNITY_IPHONE
using System;
using System.IO;
using System.Text;
using UnityEditor.iOS.Xcode;
using UnityEditor.Localization.Platform.Utility;
using UnityEngine.Localization;
using UnityEngine.Localization.Platform.iOS;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using Debug = UnityEngine.Debug;

namespace UnityEditor.Localization.Platform.iOS
{
   public static class Player
   {
       const string k_InfoFile = "InfoPlist.strings";

       static PackageManager.PackageInfo s_PackageInfo;
       static PackageManager.PackageInfo LocalizationPackageInfo
       {
           get
           {
               if (s_PackageInfo == null)
               {
                   s_PackageInfo = PackageManager.PackageInfo.FindForAssembly(typeof(LocalizationSettings).Assembly);
               }
               return s_PackageInfo;
           }
       }

       /// <summary>
       /// Updates the Xcode project file with localized values using the <see cref="AppInfo"/> from <see cref="LocalizationSettings.Metadata"/>.
       /// </summary>
       /// <param name="projectDirectory">The root project directory to be updated. This is where the iOS player was built to.</param>
       /// <param name="appInfo"></param>
       public static void AddLocalizationToXcodeProject(string projectDirectory)
       {
           var appInfo = LocalizationSettings.Metadata.GetMetadata<AppInfo>();
           if (appInfo == null)
               return;
           AddLocalizationToXcodeProject(projectDirectory, appInfo);
       }

       /// <summary>
       /// Updates the Xcode project file with localized values using <see cref="AppInfo"/>.
       /// </summary>
       /// <param name="projectDirectory">The root project directory to be updated. This is where the iOS player was built to.</param>
       /// <param name="appInfo">Contains the localized values for the App.</param>
       public static void AddLocalizationToXcodeProject(string projectDirectory, AppInfo appInfo)
       {
           if (appInfo == null)
               throw new ArgumentNullException(nameof(appInfo));

           var pbxPath = PBXProject.GetPBXProjectPath(projectDirectory);
           var project = new PBXProject();
           project.ReadFromFile(pbxPath);
           project.ClearKnownRegions(); // Remove the deprecated regions that get added automatically.

           var plistDocument = new PlistDocument();
           var plistPath = Path.Combine(projectDirectory, "Info.plist");
           plistDocument.ReadFromFile(plistPath);

           // Default language
           // How iOS Determines the Language For Your App - https://developer.apple.com/library/archive/qa/qa1828/_index.html
           var developmentRegion = string.IsNullOrEmpty(LocalizationSettings.Instance.m_ProjectLocaleIdentifier.Code) ? LocalizationEditorSettings.GetLocales() ? [0]?.Identifier : LocalizationSettings.Instance.m_ProjectLocaleIdentifier;
           if (developmentRegion.HasValue)
               project.SetDevelopmentRegion(developmentRegion.Value.Code);
           plistDocument.root.SetString("CFBundleDevelopmentRegion", "$(DEVELOPMENT_LANGUAGE)");

           // Inclusion of this key improves performance associated with displaying localized application names.
           plistDocument.root.SetBoolean("LSHasLocalizedDisplayName", true);

           var bundleLanguages = plistDocument.root.CreateArray("CFBundleLocalizations");
           foreach (var locale in LocalizationEditorSettings.GetLocales())
           {
               var code = locale.Identifier.Code.Replace("-", "_");
               project.AddKnownRegion(code);
               bundleLanguages.AddString(code);

               var localeDir = code + ".lproj";
               var dir = Path.Combine(projectDirectory, localeDir);
               Directory.CreateDirectory(dir);

               var filePath = Path.Combine(dir, k_InfoFile);
               var relativePath = Path.Combine(localeDir, k_InfoFile);

               GenerateLocalizedInfoPlistFile(locale, appInfo, plistDocument, filePath);
               project.AddLocaleVariantFile(k_InfoFile, code, relativePath);
           }

           // Defaults
           var projectLocale = LocalizationSettings.ProjectLocale;
           if (projectLocale != null)
           {
               WriteDefaultLocalizedValue("CFBundleName", projectLocale, appInfo.ShortName, plistDocument);
               WriteDefaultLocalizedValue("CFBundleDisplayName", projectLocale, appInfo.DisplayName, plistDocument);
               WriteDefaultLocalizedValue("NSCameraUsageDescription", projectLocale, appInfo.CameraUsageDescription, plistDocument);
               WriteDefaultLocalizedValue("NSMicrophoneUsageDescription", projectLocale, appInfo.MicrophoneUsageDescription, plistDocument);
               WriteDefaultLocalizedValue("NSLocationWhenInUseUsageDescription", projectLocale, appInfo.LocationUsageDescription, plistDocument);
               WriteDefaultLocalizedValue("NSUserTrackingUsageDescription", projectLocale, appInfo.UserTrackingUsageDescription, plistDocument);
           }
           else
           {
               Debug.LogWarning("Project Locale was not configured. Can not set default IOS localized values. Configure the project locale through the Localization Settings.");
           }

           plistDocument.WriteToFile(plistPath);
           project.WriteToFile(pbxPath);
       }

       static void GenerateLocalizedInfoPlistFile(Locale locale, AppInfo appInfo, PlistDocument plistDocument, string filePath)
       {
           using (var stream = new StreamWriter(filePath, false, Encoding.UTF8))
           {
               stream.Write(
                   "/*\n" +
                   $"\t{k_InfoFile}\n" +
                   $"\tThis file was auto-generated by {LocalizationPackageInfo.name}\n" +
                   $"\tVersion {LocalizationPackageInfo.version}\n" +
                   $"\tChanges to this file may cause incorrect behavior and will be lost if the project is rebuilt.\n" +
                   $"*/\n\n");

               WriteLocalizedValue("CFBundleName", stream, locale, appInfo.ShortName, plistDocument);
               WriteLocalizedValue("CFBundleDisplayName", stream, locale, appInfo.DisplayName, plistDocument);
               WriteLocalizedValue("NSCameraUsageDescription", stream, locale, appInfo.CameraUsageDescription, plistDocument);
               WriteLocalizedValue("NSMicrophoneUsageDescription", stream, locale, appInfo.MicrophoneUsageDescription, plistDocument);
               WriteLocalizedValue("NSLocationWhenInUseUsageDescription", stream, locale, appInfo.LocationUsageDescription, plistDocument);
               WriteLocalizedValue("NSUserTrackingUsageDescription", stream, locale, appInfo.UserTrackingUsageDescription, plistDocument);
           }
       }

       static void WriteLocalizedValue(string valueName, StreamWriter stream, Locale locale, LocalizedString localizedString, PlistDocument plistDocument)
       {
           if (localizedString.IsEmpty)
               return;

           var tableCollection = LocalizationEditorSettings.GetStringTableCollection(localizedString.TableReference);
           var table = tableCollection?.GetTable(locale.Identifier) as StringTable;
           var entry = table?.GetEntryFromReference(localizedString.TableEntryReference);

           if (entry == null || string.IsNullOrWhiteSpace(entry.LocalizedValue))
           {
               // Use fallback?
               var fallBack = FallbackLocaleHelper.GetLocaleFallback(locale);
               if (fallBack != null)
               {
                   WriteLocalizedValue(valueName, stream, fallBack, localizedString, plistDocument);
                   return;
               }

               Debug.LogWarning($"{valueName}: Could not find a localized value for {locale} from {localizedString}");
               return;
           }

           Debug.Assert(!entry.IsSmart, $"Localized App Values ({valueName}) do not support Smart Strings - {localizedString}");
           stream.WriteLine($"\"{valueName}\" = \"{entry.LocalizedValue}\";");
       }

       static void WriteDefaultLocalizedValue(string valueName, Locale locale, LocalizedString localizedString, PlistDocument plistDocument)
       {
           if (localizedString.IsEmpty)
               return;

           var tableCollection = LocalizationEditorSettings.GetStringTableCollection(localizedString.TableReference);
           var table = tableCollection?.GetTable(locale.Identifier) as StringTable;
           var entry = table?.GetEntryFromReference(localizedString.TableEntryReference);
           plistDocument.root.SetString(valueName, entry?.LocalizedValue);
       }
   }
}
#endif
1 Like

Hi, I’m having a very similar issue with xcode 14.2 and Unity 2020.3.47f1. All of the identity settings are gone. When I try to archive and send to iTunes, I get errors “Signing for {package name} requires a development team”, because the dev team was gone as well. Has anyone managed to fix that?

Try updating to 1.4.3 which includes the fix for empty ios field names.
You may need to manually edit the manifest.json file in the Packages folder if its not visible in the package manager.

thanks for your reply @karl_jones , I’ve updated Xcode to 14.3 but am facing the same issue. nothing changed as far as I’m concerned. What do you mean by updating from manifest? The issues are related to facebook SDK and all the other SDKs that don’t get signed (quite a few of them)

I thought you were having the same issue as this thread. If it’s a signing issue then it doesn’t sound related to localization. You will need to sign your app with a valid iOS developer license
https://docs.unity3d.com/Manual/iphone-GettingStarted.html

Maybe this is not the right thread. I also found this one https://forum.unity.com/threads/identity-lost-on-xcode-14-2.1376223/#post-8942706 This is the issue I’m having. It cannot be signed not because I don’t have a valid certificate but because the Signing Team ID field is empty when exporting to XCode

I’m using the latest 2022 LTS (2022.3.22), and when I build for iOS, and open the generated XCode project in the latest version (15.3), I have the same issue as OP. All my info is missing, display name, orientation, etc.
Has there been any update to this?
Thank you!

I was about to bump this thread but this one is fresher.

Unity 2022 LTS → Xcode 15.x created the same issue.
Every time the project will be recreated (instead of appended) the issue shall return.

#4

Are you sure of that? Why should there be different info.plist files?

Try the latest version of the package 1.5.1. If its not visible in the package manager you can edit the manifest.json file in the Packages folder to force an upgrade,

If you still have the issue please file a bug report.

Can you confirm, what package?
Thank you!

The localization package. If this is not related to the localization package then you’re in the wrong place. Try https://forum.unity.com/threads/identity-lost-on-xcode-14-2.1376223/#post-8942706

Thank you for the suggestion. That thread hasn’t been updated in months either, but I will give it a try.

1 Like

I didn’t even know this package was required. It was not present in my project.
I cannot get any version higher than 1.4.5. Am I supposed to fetch a beta version of the 1.5.1? A Git link maybe?

Also I’m not sure what this really does. The Identity part doesn’t prevent builds and the app is properly named but if the General data in Xcode doesn’t present what would be expect to be there, it’s bizarre. That might cause issues when doing the archive and or uploading the app.

Also, you said there are two info.plist files in use?
Is that even legal? :slight_smile:
And where is the cousin file then? The info.plist at the root of the folder where Unity builds the iOS project does contain the proper data, so unless I’m wrong here, am I supposed to understand that Xcode is looking into another info.plist file somewhere else?

There’s confusion in this thread between something that was an issue with the localization package and it’s xcode exporting and something else unrelated that involves xcode. Sounds like you have a different issue. The other thread seems more appropriate for your problem https://forum.unity.com/threads/identity-lost-on-xcode-14-2.1376223/#post-8942706

Perhaps yes. To note, the build does work and the name appears under the app’s icon.