iosipadoscfbundleicons

Alternate Icons not included in iPadOS build of app's CFBundleAlternateIcons


I'm developing a SwiftUI app and have implemented app icon switching. I walk the list of CFBundleAlternateIcons from the main bundle's CFBundleIcons key at runtime to display the list of options the user can select from.

All is well when running on iOS (device or simulator). However, none of the alternate icons are available when running on iPadOS (device or simulator).

The project is set up with Include all app icon assets checked on the app target, and all the icon sets are in the main asset catalog and are configured as Single Size for iOS. Based on some old StackOverflow posts I've also tried switching them to All Sizes and explicitly adding images for each variant, to no avail.

Just in case, I also toggled Include All App Icon Assets to Yes the project level, which had no effect. The project and app target are set with a deployment target of iOS 16.0.

Using xcrun --sdk iphoneos assetutil --info on the iPad build's Assets.car file shows the relevant entries for the icon files. For example:

{
    "AssetType" : "MultiSized Image",
    "Idiom" : "pad",
    "Name" : "BlackIcon",
    "NameIdentifier" : 25144,
    "Scale" : 1,
    "SHA1Digest" : "3ADDEA1FD56367BF89B8931F5D01A583F6D8C6D47EAAB8F4BB5E7FE61D7D9596",
    "SizeOnDisk" : 236,
    "Sizes" : [
      "1024x1024 index:0 idiom:pad"
    ]
  }

And inspecting the .car file with Asset Catalog Tinkerer shows that the various alternate icon images are indeed present.

And yet, CFBundleAlternateIcons is nil when accessing the main bundle when running the app on iPadOS.

Even attempting to just directly set one of the alternate icons by name results in the error

UserInfo={_LSLine=198, NSUnderlyingError=0x60000290e400 {Error 
Domain=LSApplicationWorkspaceErrorDomain Code=-105 "iconName not found in 
CFBundleAlternateIcons entry" UserInfo={_LSLine=186, NSLocalizedDescription=iconName 
not found in CFBundleAlternateIcons entry, _LSFunction=-[LSAltIconManager 
_setAlternateIconName:forIdentifier:withIconsDictionary:error:]}}, _LSFunction=-
[LSAltIconManager _setAlternateIconName:forIdentifier:withIconsDictionary:error:]} The
 file doesn’t exist.

I tried to replicate the behaviour with a new project, even using the same source image files as in my project's icon sets, and everything worked as one would expect on iPadOS. So I'm left to wonder if there's something awry in my project file ... maybe.

I'm at a loss for what to try/check at this point. Using Xcode 14.3 (14E222b).


Solution

  • This appears to have been fixed in the release candidate of Xcode 14.3.1! (14E300b)

    I can now see and select from the full list of alternate icons from CFBundleAlternateIcons in the SwiftUI preview pane, when running the app on an iPadOS simulator running iOS 16.0 and 16.4, and on actual iPad devices running iPadOS 16.4.1(a).