问题
Is there a way to get the current application icon in a cocoa-touch app? Thank you.
回答1:
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
.
回答2:
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.
回答3:
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!)
回答4:
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.
回答5:
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
"icon@2x.png"//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!!
回答6:
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
)
回答7:
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];
}
}
回答8:
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)
回答9:
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.
来源:https://stackoverflow.com/questions/9419261/how-to-get-the-current-application-icon-in-ios