Dynamically Change the App Icon

Since iOS 10.3, Apple launches a cool function so that developers are able to programmatically change the app icon. Although it is not that flexible as the official Clock app with a running clock, we can still enjoy great dynamism based on it. Let’s take a look at how it works.

Theory behind it

In Apple’s API document, there are 3 things worth a glance:

var supportsAlternateIcons: Bool { get }
var alternateIconName: String? { get }
func setAlternateIconName(String?, completionHandler: ((Error?) -> Void)? = nil)
  • supportsAlternateIcons is a readonly property, it decides whether the app could change its icon or not. To make it true, we need to set up alternative icons in info.plist file, we will talk about it later.
  • alternateIconName is also a readonly property, it is the name of current alternative app icon being displayed. Notice that it is nil when app is displaying its primary icon.
  • setAlternateIconName is a function to set up icon to be displayed. If we set the icon name to nil, the app will display its primary icon.

For more details, you could reference Apple’s official API page.

Since we understand how to do that, let’s go to Xcode and get started.

Prerequisites

First let us put 3 images for app icons, they are “pichu.png”, “pikachu.png”, and “raichu.png”.

Note that it is useless if we put icon images under Assets directory, the right place is under the project directory. Here is my screenshot:

Next, we need to set up the Info.plist.

  1. Add Icon files (iOS 5) to the Information Property List
  2. Add CFBundleAlternateIcons as a dictionary, it is used for alternative icons
  3. Set 3 dictionaries under CFBundleAlternateIcons, they are correspond to “pichu”, “pikachua”, and “raichu”
  4. For each dictionary, two properties — UIPrerenderedIcon and CFBundleIconFiles need to be configured

For more details, you could reference Apple’s Core Foundation Keys Page. Here is my screenshot of info.plist:

Coding Example

Let us assume we have 3 buttons in a view. Tap any of them would make the app to display a correspond icon. Here is the sample code:

// change app icon to "pichu"
@IBAction func pichuButtonDidTap(_ sender: UIButton) {
  changeIcon(to: "pichu")
}

// change app icon to "pikachu"
@IBAction func pikachuButtonDidTap(_ sender: UIButton) {
  changeIcon(to: "pikachu")
}

// change app icon to "raichu"
@IBAction func raichuButtonDidTap(_ sender: UIButton) {
  changeIcon(to: "raichu")
}

func changeIcon(to iconName: String) {
  // 1
  guard UIApplication.shared.supportsAlternateIcons else {
    return
  }

// 2
  UIApplication.shared.setAlternateIconName(iconName, completionHandler: { (error) in
    // 3
    if let error = error {
      print("App icon failed to change due to \(error.localizedDescription)")
    } else {
      print("App icon changed successfully")
    }
  })
}
  1. Check if the app supports alternating icons
  2. Change the icon to a specific image with given name
  3. After app icon changed, print our error or success message

Build and run the app, enjoy the show!

Like what you read? Give iOS Tech Set a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.