Skip to content

iOS: add support for alternate app icons #1023

Description

@tido64

Proposal

In iOS, people can choose an alternate app icon: https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons

Technically, the option is also available to macOS, but it doesn't seem like it's supported according to docs. For now, supported platforms include iOS, iPadOS, and visionOS.

Alternatives

n/a

Implementation Details

#1022 put down a lot of the foundation already. We need to add a few more props to Info.plist, such as CFBundleAlternateIcons, when alternateIcons is set.

Configuration

Alternate icons are configured under icons.alternateIcons:

{
  "ios": {
    "icons": {
      "primaryIcon": {
        "filename": "AppIcon.png",
        "prerendered": true
      },
      "alternateIcons": {
        "AppIconBlue": {
          "filename": "AppIconBlue.png",
          "prerendered": false
        },
        "AppIconRed": {
          "filename": "AppIconRed.png",
          "prerendered": true
        }
      }
    }
  }
}

Each property name under alternateIcons:

  • Is the alternate icon's unique identifier.
  • Is used as the asset-catalog name.
  • Is passed to APIs such as UIApplication.setAlternateIconName(...).
  • Must be a valid, non-reserved asset-catalog identifier.

Implementation Details

When alternateIcons contains valid entries:

  1. Generate an .appiconset for each alternate icon (similar to feat: add ability to set app icons #1022).
  2. Add each alternate icon under CFBundleIcons.CFBundleAlternateIcons in the generated Info.plist.
  3. Use the same icon-entry format as CFBundlePrimaryIcon, including:
    • CFBundleIconName
    • CFBundleIconFiles
    • UIPrerenderedIcon
  4. Set UIPrerenderedIcon from the manifest entry's prerendered value.
  5. Configure ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES with the names of all valid alternate icon sets.

For the example above, the generated plist should contain entries equivalent to:

<key>CFBundleIcons</key>
<dict>
    <key>CFBundleAlternateIcons</key>
    <dict>
        <key>AppIconBlue</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <!-- Generated icon files -->
            </array>
            <key>CFBundleIconName</key>
            <string>AppIconBlue</string>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
        <key>AppIconRed</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <!-- Generated icon files -->
            </array>
            <key>CFBundleIconName</key>
            <string>AppIconRed</string>
            <key>UIPrerenderedIcon</key>
            <true/>
        </dict>
    </dict>
</dict>

ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES should contain:

AppIconBlue AppIconRed

The exact serialization may differ as long as the generated plist and build setting are semantically equivalent.

Invalid Entries

Invalid or reserved identifiers must not fail project generation.

For each invalid entry:

  • Emit a warning identifying the ignored icon and the reason it is invalid.
  • Do not generate its asset catalog.
  • Do not add it to CFBundleAlternateIcons.
  • Do not add it to ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES.
  • AppIcon, which is reserved for the primary icon, must be treated as invalid when used as an alternate icon identifier.

Warnings should not prevent other valid alternate icons from being processed.

Additional Context

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions