In iOS 10.3, Apple launches a cool function so that developers are able to programmatically change the app icon. In Apple's UIApplication
API document, there are 3 things worth a glance:
//A Boolean value indicating whether the app is allowed to change its icon. To make it true, we need to set up alternative icons in Info.plist file.
var supportsAlternateIcons: Bool
//The name of the icon being displayed for the app. Notice that it is nil when app is displaying its primary icon.
var alternateIconName: String?
//Changes the app's icon. If we set the icon name to nil, the app will display its primary icon.
func setAlternateIconName(String?, completionHandler: ((Error?) -> Void)? = nil)
1. Prerequisite
- Set target to minimum iOS 10.3
- Add default AppIcon in Assets.xcassets
- Add your Alternate icons under your project directory (assets seems not to work)
2. Setup Info.plist
- Add
Icon files (iOS 5)
/CFBundleIcons
to the Info.plist - Add
CFBundleAlternateIcons
as aDictionary
, it is used for alternative icons - Set 3 dictionaries under
CFBundleAlternateIcons
, they are correspond to "AppIconAlternate1", "AppIconAlternate2", and "AppIconAlternate3" - For each dictionary, create one properties
CFBundleIconFiles
asArray
. The array value for keyCFBundleIconFiles
includes the icon files.
Info.plist screenshot
Info.plist source code
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AppIconAlternate1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconAlternate1</string>
</array>
</dict>
<key>AppIconAlternate2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconAlternate2</string>
</array>
</dict>
<key>AppIconAlternate3</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconAlternate3</string>
</array>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>UINewsstandIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UINewsstandBindingEdge</key>
<string>UINewsstandBindingEdgeLeft</string>
<key>UINewsstandBindingType</key>
<string>UINewsstandBindingTypeMagazine</string>
</dict>
</dict>
3. Code
Let us assume we have 4 buttons in a view. Tap any of them would make the app to display a correspond icon. Here is the sample code:
@IBAction func appIcon1Tapped(_ sender: UIButton) {
changeIcon(to: "AppIconAlternate1")
}
@IBAction func appIcon2Tapped(_ sender: UIButton) {
changeIcon(to: "AppIconAlternate2")
}
@IBAction func appIcon3Tapped(_ sender: UIButton) {
changeIcon(to: "AppIconAlternate3")
}
@IBAction func resetAppIconTapped(_ sender: UIButton) {
//Set the icon name to nil, the app will display its primary icon.
changeIcon(to: nil)
}
func changeIcon(to name: String?) {
//Check if the app supports alternating icons
guard UIApplication.shared.supportsAlternateIcons else {
return;
}
//Change the icon to a specific image with given name
UIApplication.shared.setAlternateIconName(name) { (error) in
//After app icon changed, print our error or success message
if let error = error {
print("App icon failed to due to \(error.localizedDescription)")
} else {
print("App icon changed successfully.")
}
}
}
4. Demo Video
Ref- Apple Documentation