microsoft / microsoft/react-native-test-app

iOS: add support for alternate app icons

Open
#1,023 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement platform: iOS
Dominant language
TypeScript
Stars
674
Forks
97
Avg merge
21h 43m
Merged PRs (30d)
20

Description

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 #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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read the icon-generation foundation from #1022 first, then trace where iOS asset catalogs, Info.plist entries, and build settings are generated. Done means valid alternate icons produce their asset catalogs, plist metadata, and compiler names, while invalid or reserved identifiers are skipped with warnings without blocking valid entries.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, react-native, typescript
Domain
build-system, mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.