the Reverend
the Reverend

Reputation: 12559

How to get the current application icon in ios

Is there a way to get the current application icon in a cocoa-touch app? Thank you.

Upvotes: 36

Views: 27745

Answers (11)

Robin Stewart
Robin Stewart

Reputation: 3883

A version of this answer worked best for me in SwiftUI because it allows you to choose the icon size you want (and 1x/2x/3x is chosen automatically by the system).

Image(uiImage: UIImage(named: "AppIcon60x60") ?? UIImage())
    .cornerRadius(10)

Upvotes: 5

multitudes
multitudes

Reputation: 3535

Just for clarification this is what you get when you query the CFBundleIcon dictionary as per the examples above:

(key: "CFBundlePrimaryIcon", value: {
    CFBundleIconFiles =     (
        AppIcon60x60
    );
    CFBundleIconName = AppIcon;
})

Unfortunately there are only two values which are returned. One is the AppIcon60x60 on the iPhone Mini that I have, and the other, AppIcon is even smaller!

Anybody has another hint?

Upvotes: 2

Jeshua Lacock
Jeshua Lacock

Reputation: 6668

Because it took me a little while to work out, here is a working Swift solution.

let primaryIconsDictionary = NSBundle.mainBundle().infoDictionary?["CFBundleIcons"]?["CFBundlePrimaryIcon"] as? NSDictionary
let iconFiles = primaryIconsDictionary!["CFBundleIconFiles"] as NSArray
let lastIcon = iconFiles.lastObject as NSString //last seems to be largest, use first for smallest
let theIcon = UIImage(named: lastIcon)

let iconImageView = UIImageView(image: theIcon)

Upvotes: 7

samwize
samwize

Reputation: 27363

Works for Swift 4.1 and extending it for Bundle.

extension Bundle {
    public var icon: UIImage? {
        if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
            let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
            let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
            let lastIcon = iconFiles.last {
            return UIImage(named: lastIcon)
        }
        return nil
    }
}

To use in an app, call Bundle.main.icon.

Upvotes: 34

CodeBender
CodeBender

Reputation: 36620

Here is a Swift 4.x && 3.x extension to UIApplication for obtaining the application icon. You can choose whether to get the smallest or largest icon based on the location of the icon path you pull from the iconFiles array.

extension UIApplication {
    var icon: UIImage? {
        guard let iconsDictionary = Bundle.main.infoDictionary?["CFBundleIcons"] as? NSDictionary,
            let primaryIconsDictionary = iconsDictionary["CFBundlePrimaryIcon"] as? NSDictionary,
            let iconFiles = primaryIconsDictionary["CFBundleIconFiles"] as? NSArray,
            // First will be smallest for the device class, last will be the largest for device class
            let lastIcon = iconFiles.lastObject as? String,
            let icon = UIImage(named: lastIcon) else {
                return nil
        }

        return icon
    }
}

To access the icon, call the following:

let icon = UIApplication.shared.icon

For bonus points, you could even make two vars to get the smallest and largest icon if your app needed it.

Upvotes: 20

Russ
Russ

Reputation: 1844

If you're using Xamarin:

var iconNames = NSBundle.MainBundle.InfoDictionary.ValueForKeyPath((NSString)"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles") as NSArray;
var name = iconNames.GetItem<NSString>(iconNames.Count - 1); //Grabs last item, call with 0 for the first item
var icon = UIImage.FromBundle(name);

Based on Andy's answer using the KVC method. Bit lengthy, but using KeyPath is better than chaining calls to ValueForKey.

Upvotes: 3

pronebird
pronebird

Reputation: 12240

If you use asset catalogues, then you can simply use:

UIImage* appIcon = [UIImage imageNamed:@"AppIcon60x60"];

Asset catalogues seem to standardize filenames for app icons.

Certainly if you need to list all app icons in your bundle you can look it up in CFBundleIconFiles branch of info dictionary.

Using KVC you can easily get that in a single line of code:

NSArray* allIcons = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"];

Resulting array will contain all app icon names available in your bundle. Any of these names can be used to retrieve icon using +[UIImage imageNamed:]

<__NSCFArray 0x15d54260>(
    AppIcon29x29,
    AppIcon40x40,
    AppIcon60x60
)

Upvotes: 14

Siegfoult
Siegfoult

Reputation: 1839

The accepted answer did not work for me, I am using Xcode 5's Images.xcassets method of storing app icons. This modification worked for me:

UIImage *appIcon = [UIImage imageNamed: [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"]  objectAtIndex:0]];

When in doubt, just explore the main bundle's infoDictionary using lldb.

Upvotes: 18

Constantino Tsarouhas
Constantino Tsarouhas

Reputation: 6886

I based my answer completely on moosgummi's, but returning a UIImage instead.

UIImage *appIcon = [UIImage imageNamed: [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];

The UIImage automatically selects the suitable version (normal, @2x, ~ipad, ~ipad@2x or any future suffix). (BTW, don't you just hate this stupid scheme for identifying versions of images? It was just getting out of hand. Thank god for Asset Catalogues!)

Upvotes: 14

Sumit
Sumit

Reputation: 944

This is how the icons is set inside the info.plist,

//try doing NSLog(@"%@",[[NSBundle mainBundle] infoDictionary]);

 CFBundleIcons =     {
        CFBundlePrimaryIcon =         {
            CFBundleIconFiles =             (
                "icon.png",//App icon added by you
                "[email protected]"//App icon in retina added by you
            );
            UIPrerenderedIcon = 1;
        };
    };

If you want to get the app icon use below code:

UIImage *appIcon = [UIImage imageNamed: [[[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIcons"] objectForKey:@"CFBundlePrimaryIcon"] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];

P.S: UIImage automatically picks the suitable icon for retina display.

I hope it helps!!

Upvotes: 10

dom
dom

Reputation: 11962

Thats easy, because the filename of the current icon is set in Info.plist:

NSString *filePath = [[NSString alloc] initWithString:[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"] objectAtIndex:0]];

If you want to pick the high-res version you should use:

NSString *filePath = nil;    
for (NSString *fileName in [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIconFiles"]) {
    if ([fileName rangeOfString:@"@2x"].location != NSNotFound) {
        filePath = [[NSString alloc] initWithString:fileName];
    }
}

Upvotes: 9

Related Questions