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.
<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))")
}
}
}
}
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
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>Icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater1</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>Icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater2</string>
</array>
</dict>
</dict>
</dict>
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()
Unable to set alternate app icons in iOS 11
I solved this by implementing it in a ViewController, rather than the AppDelegate's appDidFinishLaunchingWithOptions
Still need to run it within a delay for it to work though, as related questions / answers point out.
Is alternative icon available for watchOS?
watchOS does not support alternate icon, as of watchOS 4.0 beta.
I ended up answering Apple Review team, the app is intended to not provide alternate icons in Watch App.
Related Topics
Letter by Letter Animation for Uilabel
Cocoapods Could Not Find Compatible Versions for Pod "Firebase/Core" | Cloud_Firestore, Flutter
Swift: Long Press Gesture Recognizer - Detect Taps and Long Press
Library Not Found for -Ldoubleconversion
How to Catch All iOS Push Notifications with Different User Actions Including Tap on App Icon
Swift - How to Record Video in Mp4 Format with Uiimagepickercontroller
How to Get the iOS Device CPU Architecture in Runtime
Get Date and Time from Apple Server
How to Do Authentication in Uiwebview Properly
iOS Cllocationmanager in a Separate Class
How to Figure Out Which Url Is Being Blocked by App Transport Security
Push Notifications Not Being Received on iOS 10, But Working on iOS 9 and Before
Convert Nsdate to String in iOS Swift
Ios: How to Run a Function After Device Has Rotated (Swift)
Xcode Version 6.1 (6A1030) - Apple MACh O-Linker Error - Building
How to Programmatically Use iOS Voice Synthesizers? (Text to Speech)
Open Uisplitviewcontroller to Master View Rather Than Detail