Alternate Icon in iOS 10.3

Since the biggest problem is how to configure the icon image source and info.plist, here is a sample to tell you how to set alternate icons in iOS 10.3, implemented in Swift 3.

Assets.xcassetsinfo.plist

  1. If your app doesn't support iPad, the icon image source can be 60pt@2x and 60pt@3x (120x120 180x180), and the 20pt 29pt and 40pt all can be generated from the 60pt image. So, your alternate icon image source should also be 60pt@2x and 60pt@3x, if it is a iPhone-only app. And it should be 83.5pt, if your app supports iPad Pro.

  2. Like what you saw in the picture, the alternate icon image should be added to the project as a png file (the blackBgColor image in my sample), but not added to Assets.xcassets.

  3. The configuration for alternate icons in info.plist is kinda complicated, so if this is your first time doing this, I suggest you copy my code in plist. And, notice my alternate icon's name (blackBgColor) has beed used TWICE in plist, if you are gonna change the icon's name based on my version, make sure you changed the name in both of the two places.

    <key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>blackBgColor</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>blackBgColor</string>
                </array>
                <key>UIPrerenderedIcon</key>
                <false/>
            </dict>
        </dict>
        <key>CFBundlePrimaryIcon</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <string>AppIcon60x60</string>
            </array>
        </dict>
    </dict>
    

Now, code in ViewController will be simple.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func changeAppIcon(_ sender: Any) {

        if UIApplication.shared.supportsAlternateIcons {
            print("you can change this app's icon")
        }else {
            print("you cannot change this app's icon")
            return
        }

        if let name = UIApplication.shared.alternateIconName {
            // CHANGE TO PRIMARY ICON
            UIApplication.shared.setAlternateIconName(nil) { (err:Error?) in
                print("set icon error:\(String(describing: err))")
            }
            print("the alternate icon's name is \(name)")
        }else {
            // CHANGE TO ALTERNATE ICON
            UIApplication.shared.setAlternateIconName("blackBgColor") { (err:Error?) in
                print("set icon error:\(String(describing: err))")
            }
        }
    }

}

To change the icon you need to use set​Alternate​Icon​Name(_:​completion​Handler:​)

You need to put the CFBundleAlternateIcons in Info.plist. The Alternate icon sizes are same as of primary icon sizes listed here.

You can read full docs in Contents of the CFBundleAlternateIcons Dictionary Entry

enter image description here


Edit: This excerpt is from the above docs icon sizes listed here

Provide visually consistent alternate icons in all necessary sizes. Like your primary app icon, each alternate app icon is delivered as a collection of related images that vary in size. When the user chooses an alternate icon, the appropriate sizes of that icon replace your primary app icon on the Home screen, in Spotlight, and elsewhere in the system. To ensure that alternate icons appear consistently throughout the system—the user shouldn't see one version of your icon on the Home screen and a completely different version in Settings, for example—provide them in the same sizes you provide for your primary app icon (with the exception of the large App Store icon). See App Icon Sizes