App icons are the first point of engagement for your users, an effective tool to catch their attention, and keep them away from exploring other potential options. Having alternative icon options is a great way to bring some personality to your app, and it’s also fairly simple to set up.
Prerequisite
The ability to change app icons has been present since iOS 10.3, so please make sure you have a recent build of Xcode.
To get started, you will first need some icons. I like to use Figma to design mine, and there is an extension called “App Icon Toolkit” which exports your icon with the correct sizes as well as naming convention.
Xcode
In Xcode, I have created a new group called “AlternativeIcons” to organize my icons. Each image should be available in both 2x (120 x120) and 3x (180 x 180) sizes, 1x size is optional. Please ensure to use the @2x and @3x naming convention that will allow iOS to automatically select the correct icon with the best resolution for the user’s device.
Important: Please ensure that these icons do not go inside the Asset catalogue.
Implementation
Next, we are going to create another Swift file called IconManager. In this file, we will create a class called IconManager that will contain three things - a constant, an enum, and a function.
public class IconManager {
private let application = UIApplication.shared
public enum AppIcon: String { // 1
case charmanderIcon
case pikachuIcon
}
public func changeAppIcon(to appIcon: AppIcon?) { // 2
let newIcon = appIcon ? appIcon.rawValue : nil // 3
application.setAlternateIconName(newIcon) // 4
}
}
- We're creating an Enum for type-safety., with the same naming convention, as in the
.plist
file, to reference to names of the files. - The public method allows for consumers to switch the App Icon based on the enum's raw value.
- First we're checking if we have a new icon.
nil
is a valid option to switch back to the default icon.
Property List
Next, go to the project navigator, right click on the Info.plist
file, and choose "Open as Source Code". Scroll to the bottom until you see:
</dict>
</plist>
Directly before </dict>
, add the following code snippet.
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>58-1</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>charmanderIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>charmander</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>pikachuIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>pikachu</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
</dict>
The key CFBundlePrimaryIcon
refers to your default icon, the key CFBundleIconFiles
refers to the file that contains your primary icon, and in between the two <string>
tags should be the name of your primary icon.
You can find this by going to your assets folder - AppIcons - find the 2x iPhone app icon - right click - select show in finder. Everything before .png
should be the name of your image, excluding the 1x / 2x/ 3x
naming convention. For example, my files are named 58-1@2x.png
, so I would put 58-1
between the <string>
tags.
Moving on to CFBundleAlternateIcons
. In the example XML
, I used the references charmanderIcon
and pikachuIcon
as keys.
In IconManager.swift
, in changeAppIcon()
function, I am setting the icon names as raw value of each case. As such, we have to use the same reference name inside the Info.plist
file, so Xcode knows what to look for.
The same name that you gave to the icons inside AlternativeIcons
will go in between the <string>
tags.
Action to change the Icon
Lastly, we need to add an action to call the IconManager's
functionality and implement the Icon switch. One option would be to add a Button and the sample code below.
private let iconManager = IconManager() // 1
@IBAction func defaultIconTapped(_ sender: Any) {
iconManager.changeAppIcon(to: nil)
}
@IBAction func charmanderTapped(_ sender: Any) {
iconManager.changeAppIcon(to: .charmanderIcon)
}
@IBAction func pikachuTapped(_ sender: Any) {
iconManager.changeAppIcon(to: .pikachuIcon)
}
- First we need access to the
IconManager
, you may choose dependency injection or directly create an instance where you need it. - The remainder of the code is fairly self explanatory. We have 3 different hypothetical buttons and are setting the respective Icon.
Result
When you run your project and tap on each alt icon button, you should see a pop up alert notifying you, that the icon has been changed successfully.
New article 🎉☺️
— David Seek (@DavidSeek) February 2, 2021
This one has been sitting on draft for a while. I'm talking about my past, my career and how I got into FAANG.
Less technical, and more personal.
Retweet and like for reach highly appreciated 🥰https://t.co/EWskDl5Jmm