最常见的就是活动来临之前,我们可以经常看到各大电商平台的应用图标在没有应用更新的时候就自动更换了图标,其实这个就涉及到了动态更换应用图标的功能。此处记录一下开发过程中遇到的一个使用动态更换应用图标的问题。

iOS15之前

在 iOS15 之前,实际上 iOS 已经支持了动态更换应用图标的功能,其核心点就是通过手动配置 info.plist 文件,保证切换图标可以通过对应的 info.plist 文件进行查询,同时需要在应用对应的资源文件中放入需要切换的图标资源才可以。整体流程相对来讲比较麻烦。

此处应用图标添加的有 20、29、40、60、76、83.5 六种,实际上可能不需要这么多,只是为了保持和在 Assets -> AppIcon 图标尽量一致而已,且此处是包含 iPhone 和 iPad 的图标的。

其中 iPhone 对应的图标是 20、29、40、60 四种;iPad 对应的图标是 29、40、60、76、83.5 五种。

当添加完资源图标后,需要在 info.plist 文件中开始配置相应参数,以保证在切换图标时可以查找的到。

/// info.plist 文件
<key>CFBundleIcons</key>
    <key>CFBundleAlternateIcons</key>
        <key>AppIcon_52B9EB</key>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon_52B9EB_20</string>
                <string>AppIcon_52B9EB_29</string>
                <string>AppIcon_52B9EB_40</string>
                <string>AppIcon_52B9EB_60</string>
            </array>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
        <key>AppIcon_5AC36E</key>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon_5AC36E_20</string>
                <string>AppIcon_5AC36E_29</string>
                <string>AppIcon_5AC36E_40</string>
                <string>AppIcon_5AC36E_60</string>
            </array>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
    </dict>
</dict>
<key>CFBundleIcons~ipad</key>
    <key>CFBundleAlternateIcons</key>
        <key>AppIcon_52B9EB</key>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon_52B9EB_29</string>
                <string>AppIcon_52B9EB_40</string>
                <string>AppIcon_52B9EB_60</string>
                <string>AppIcon_52B9EB_76</string>
                <string>AppIcon_52B9EB_83.5</string>
            </array>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
        <key>AppIcon_5AC36E</key>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon_5AC36E_29</string>
                <string>AppIcon_5AC36E_40</string>
                <string>AppIcon_5AC36E_60</string>
                <string>AppIcon_5AC36E_76</string>
                <string>AppIcon_5AC36E_83.5</string>
            </array>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
    </dict>
</dict>

说明一下:

  • CFBundleIconsCFBundleIcons~ipad 分别是对应的 iPhone 和 iPad 的图标更换适配;
  • CFBundleAlternateIcons 的 value 值是以键值对形式存在的字典,每一个 key 就是对应的图标名称,到时候就是根据这个名称去查找图片资源的;
  • 比如 AppIcon_52B9EB 就是对应的图标资源名称;
  • 图标不能有圆角、透明度,不能有 alpha 通道。
  • iOS15及之后

    iOS15 及之后,Apple 官方为了方便更换应用图标,以应对更加灵活的市场,对动态更换应用图标功能做了一些调整。而该方式的原理实际上就是将之前通过 info.plist 的获取图标的方式,通过 Include All App Icon AssetsAssets 中的应用图标集自动添加到 info.plist 中,方便读取。

    iOS15及之后,只需要通过 Assets -> + -> iOS -> iOS App Icon 的方式新建一个 AppIcon 图标集,并自定义名称。

    再之后,通过 项目工程 -> TARGETS -> Build Settings -> 搜索 Include All App Icon Assets,并将其参数值更改为 YES 即可。

    另外此种方式需要通过苹果官方审核才能在线上使用,届时可以通过 App Store Connect 后台管理网站进行切换应用图标。

    (由于需要兼容 iOS15 以下的系统,所以此种方式并未进行线上审核测试,只是进行了本地代码测试)

    /// 获取当前所有的 AppIcon 集
    if let iconsDict = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as? [String:Any] {
        if let alternateIcons = iconsDict["CFBundleAlternateIcons"] as? [String:Any] {
            debugPrint(alternateIcons.keys)
            alternateIcons.keys.forEach { item in
                debugPrint(item)
    /// 更换应用图标
    UIApplication.shared.setAlternateIconName(iconName) { error in
        if error != nil {
            HUD.flashFailure("更换应用图标失败\n\(String(describing: error?.localizedDescription))")
    /// 恢复默认应用图标
    UIApplication.shared.setAlternateIconName(nil, completionHandler: nil)
    

    如果更换成功会有如下弹框样式:

  • 掘金 - Ztfiso - iOS15 切换上架App图标的最新方案
  • 掘金 - 邓小胖先生 - iOS动态切换AppIcon
  • 原文作者苜蓿鬼仙(苜蓿、jijiucheng)

    原文链接GitHub.io - 苜蓿鬼仙 - 【iOS】iOS动态更换应用图标

    发表日期:2022/08/17 17:00:00

    更新日期:2022/08/17 17:00:00

    GitHubGitHub - jijiucheng

    个人博客GitHub.io - 苜蓿鬼仙

    小专栏小专栏 - 苜蓿鬼仙

    掘金掘金 - 苜蓿鬼仙

    微博微博 - 苜蓿鬼仙

    公众号微信 - 苜蓿小站

    小程序微信 - 苜蓿小站

    私信