Alternate Icon in iOS 10.3

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.

Assets.xcassets
info.plist

  1. 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.

  2. 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.

  3. 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).

Screenshot

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



Leave a reply



Submit