Last week I received a message from Fons Sonnemans who is porting his awesome Minesweeper 10 game from UWP to Uno Platform. He said he was facing a weird issue with his app on iOS, where the app icon was not showing up after deploying. He also posted a screenshot of the issue on Twitter:
I can't get the Icon of my iOS (#Uno/#Xamarin) app correct. It shows the default icon instead of my AppIcons. #help #dta pic.twitter.com/6XiuAJLmQe
— Fons Sonnemans 🇳🇱 (@fonssonnemans) May 7, 2020
I originally thought it could be caused by a low iOS version target (which has caused me issues before in other things), but surprisingly it was not that. In the Visual Studio asset editor and Info.plist
all seemed perfectly fine. Even the .csproj
contained all the <ImageAsset>
references:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ItemGroup> | |
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\iPad-76×76%402x.png"> | |
<Visible>false</Visible> | |
</ImageAsset> | |
… | |
</ItemGroup> |
Even then, the Simulator still kept showing the same old default iOS app icon. I asked Fons if he would be willing to provide me access to the repo so that I could run it locally on my Mac, to check if it is not some kind of caching issue – but that wasn’t the case either and the icon was still missing.
Let’s solve this mystery together!
Suspicious build output
After a while searching the internet I came onto this Stack Overflow answer by mamcx for a similar problem (emphasis mine):
Did you check the build warnings when you compiled the app. You should see a bunch of warnings about missing .png files in the AppIcon image set.
Unlike Xcode, VS requires a reference to each iOS asset .png file in the .csproj file as well as the Assets.xcassets Contents.json file. It’s redundant; but it’s just how VS works.
At first glance, this seemed to lead nowhere, as I previously confirmed the <ImageAsset>
references were, in fact, present in the .csproj
file. But out of curiosity I made a search for .png
in the Build Output window and found 18 messages like this:
The file “iphone_60x60@2x.png” for the image set “AppIcons” does not exist.
Why would the file not exist? It is clearly visible in the asset editor and it is in the .csproj
– something really funky is going on here!
Include those files!
If Visual Studio thinks the image files are missing, let’s include them “by force”! In Solution Explorer, I clicked the Show All Files button on the top. There I saw the Media.xcassets
folder and right-clicked it and selected Include In Project. What I got were now essentially two copies of the same images in the project – once as part as the Asset Catalogs and once in the Media.xcassets
folder:

I thought this can’t change anything, but went ahead and tried to run the app again, just to be sure. To my surprise – it worked! The app icon was now there, smiling at me from the iPad’s home screen:

But… why?
It was great it now worked, but why? Luckily, the answer is really close now.
I opened the .csproj
file to see what is in there. At first glance it seemed Visual Studio just included the same files twice, just without the <Visible>false</Visible>
modifier, so the new copy was actually visible in the Solution Explorer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ItemGroup> | |
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\ipad-76×76%402x.png" /> | |
… | |
</ItemGroup> |
Looks the same… but what if we look at the two side by side?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ItemGroup> | |
<ImageAsset Include="Media.xcassets\AppIcon.appiconset\iPad-76×76%402x.png"> | |
<Visible>false</Visible> | |
</ImageAsset> | |
… | |
</ItemGroup> |
Aha! ipad
vs iPad
! Could it be the uppercase? The Contents.json
file referenced the lowercase versions of the image files, but .csproj
originally used the one with uppercase “P” in the filenames.
This would normally not be a problem, as Windows is case insensitive, but macOS/iOS is not! It turns out that while copying the project files to the output, Visual Studio uses the casing specified in the .csproj
file, not the one which the files had originally. I confirmed this by going into the build cache folder on Mac (/User/Library/Caches/Xamarin/mtbs/builds):

I deleted the build cache, reverted all changes, and then modified the .csproj
file to use lowercase versions of the file names in <ImageAsset>
elements. Rebuilt and deployed and app icon was there again – but, as the masked magician would say, now we know the secrets!

Mystery solved!
The main takeaway I have from this puzzle is that file casing matters when building cross-platform apps, especially because both Android and iOS are Unix-like and are case sensitive. Also, I will try to remember to read the build output warning messages more closely, as they were telling the truth all along!
Your file name is different. In first one it’s \AppIcon.appiconset\ in second one it’s \AppIcons.appiconset\ notice the AppIcon”S”
You are right, fixed 🙂 ! The reason I copied the second snippet from another project when I tried to reproduce the problem from the start. But the file name casing issue still causes the image not showing up.
Great article… I guess we better be careful and have all the image names in lowercase
Thanks for this article. This mostly solved my issue. However, the icon will not appear on devices where it has been missing before. It shows up on those devices and emulators, where my app has not been installed yet.
The icon does show up while the app is installing and in settings, but once its installed the icon disappears.
This happens both through TestFlight and normal Debugging. Deleting the app, restarting the phone and fresh install does not help either, neither does deleting bin and obj folders or certificates on the phone. This should not effect any actual users, but is still quite frustrating. Do you have an idea what could solve this?
Changing my app bundle id finally solved the issue. However, this option was only available as my App has not been published to end users yet.