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.
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.
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.
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.
CFBundleIcons
CFBundleAlternateIcons
blackBgColor
CFBundleIconFiles
blackBgColor
UIPrerenderedIcon
CFBundlePrimaryIcon
CFBundleIconFiles
AppIcon60x60
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))")
}
}
}
}
iOS - How to set/change/reset Application Icons programatically?
It is possible to change appIcon from iOS 10.3. For this you need to set supportsAlternateIcon
to Yes
in info.plist. Both primary and secondary icons should be added in CFBundleIcons key of your app's Info.plist file.
To change App Icon following UIApplication method is to be called:
func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Void)? = nil)
Reference
Changing alternate icon for iPad
Your info.plist is structured incorrectly.
You have:
- CFBundleIcons
- CFBundleAlternateIcons
- Icon Name
- CFBundleIconFiles
- CFBundleIconFiles~ipad
But it should be:
- CFBundleIcons
- CFBundleAlternateIcons
- Icon Name
- CFBundleIconFiles
- CFBundleIcons~ipad
- CFBundleAlternateIcons
- Icon Name
- CFBundleIconFiles
Basically, once you have it working with iPhone icons, CFBundleIcons
, duplicate the entire tree as CFBundleIcons~ipad
. The iPad files shouldn't be nested under CFBundleIcons
at all.
You're mixing up CFBundleIcons~ipad
and CFBundleIconFiles~ipad
(which isn't a valid key).
iOS 10.3 - How to change app icon programmatically
Yes, iOS 10.3 finally gives developers the ability to change their app’s icon programmatically.
It is possible to change appIcon from iOS 10.3. For that you need to set supportsAlternateIcon
to Yes
in info.plist
.
Both primary and secondary icons should be added in CFBundleIcons
key of your app's Info.plist
file.
//Info.plist
CFBundleIcons
CFBundleAlternateIcons
Icon1
CFBundleIconFiles
alternater1
UIPrerenderedIcon
Icon2
CFBundleIconFiles
alternater2
To change App Icon following UIApplication method needs to be called:
Objective C:
[[UIApplication sharedApplication] setAlternateIconName:@"alternater2" completionHandler:^(NSError * _Nullable error) {
NSLog(@"Error...");
}];
Swift 3:
if UIApplication.shared.supportsAlternateIcons{
UIApplication.shared.setAlternateIconName("alternater2", completionHandler: { (error) in
print(error ?? "")
})
}
For more detailed tutorial, See:
Apple Document: setAlternateIconName(_:completionHandler:)
How to change your app icon dynamically with setAlternateIconName()
Is there any way to change the icon of my app dynamically in iOS?
step1:
Design your alternative App Icons and export them in two sizes:
120px (60px @2x)
180px (60px @3x)
Add the icons to your project under a new directory App Icons. Note that the alternate icons files must to be in the Project directory, not in the Assets directory.
Step 2: Register your new Icons in the Info.plist file
First, add a new CFBundleIcons entry (Icon files (iOS 5)), then add another entry CFBundleAlternateIcons.
CFBundleAlternateIcons entry in Info.plist
For each alternate icon, add a new entry in the infos.plist file, under CFBundleAlternateIcons. The name of the entry is the name of the icon which will be used later in your Xcode project, and the string value of the item is the name of the icon file that you added in the project at Step 1.
App icons entries in Info.plist
Once you’ve added all your icons in Info.plist, your alternate icons are ready to be used in your App.
Step 3: The App Icon Manager
The Apple API to switch App Icons is quite simple and consists of 3
var/functions:
var supportsAlternateIcons: Bool { get }
open func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Void)? = nil)
open var alternateIconName: String? { get }
As per the Apple Documentation, supportsAlternateIcons will be true when the system allows you to change the icon of then App, or false otherwise.
The setAlternateIconName method is used to change the App Icon to its primary icon or to one of its alternate icons. If alternateIconName is nil then the default App Icon will be used.
Finally, alternateIconName returns the name of the alternate icon currently used, or nil if the default icon is used.
To handle icon changes easily, we will create an Icon Manager to interact with Apple APIs. First, create an enum containing each of your alternate App Icons.
enum BMAppIcon: CaseIterable {
case classic,
cookie,
donut,
cake,
iceCream
}
Now let’s add the file name of each of our icon in the enum, and a preview icon that will be displayed in our App UI. In our enum, classic is the default app icon. That’s why the file name for it will be nil. For more information on why the file name is nil you can check the alternateIconName description on Apple documentation.
var name: String? {
switch self {
case .classic:
return nil
case .cookie:
return "cookieIcon"
case .donut:
return "donutIcon"
case .cake:
return "cakeIcon"
case .iceCream:
return "iceCreamIcon"
}
}
var preview: UIImage {
switch self {
case .classic:
return #imageLiteral(resourceName: "cake@2x.png")
case .cookie:
return #imageLiteral(resourceName: "cookie@2x.png")
case.donut:
return #imageLiteral(resourceName: "donut@2x.png")
case .cake:
return #imageLiteral(resourceName: "cake@2x.png")
case .iceCream:
return #imageLiteral(resourceName: "iceCream@2x.png")
}
}
Now that we have our enum, let’s create an AppIconManger class with two functions: one to retrieve the current App Icon, and one to update it.
var current: BMAppIcon {
return BMAppIcon.allCases.first(where: {
$0.name == UIApplication.shared.alternateIconName
}) ?? .classic
}
func setIcon(_ appIcon: BMAppIcon, completion: ((Bool) -> Void)? = nil) {
guard current != appIcon,
UIApplication.shared.supportsAlternateIcons
else { return }
UIApplication.shared.setAlternateIconName(appIcon.name) { error in
if let error = error {
print("Error setting alternate icon \(appIcon.name ?? ""): \(error.localizedDescription)")
}
completion?(error != nil)
}
}
Step 4: Use your App Icon Manager in your App
Final step, to update the current App Icon, just call the setIcon function you previously defined and pass the new icon you want to set as parameter.
Related Topics
Ios 7 Textkit - How to Insert Images Inline With Text
Ineligible Devices Section Appeared in Xcode 6.X.X
Detect If the App Was Launched/Opened from a Push Notification
How to Create Ns_Options-Style Bitmask Enumerations in Swift
How to Receive Nsnotifications from Uiwebview Embedded Youtube Video Playback
Storyboard Doesn't Contain a View Controller With Identifier
How to Support Universal Links in iOS App and Setup Server For It
How to Change the Device Orientation Programmatically in iOS 6
Iterate Over Snapshot Children in Firebase
When Should We Use "Embedded Binaries" Rather Than "Linked Frameworks" in Xcode
How to Add a Touch Event to a Uiview
Uisegmentedcontrol Below Uinavigationbar in iOS 7
Adding Images or Videos to iPhone Simulator