50

I am using Assets Catalog, and adding app icon of various size to the assets is okay.

But when I tried to get the UIImage programmatically, it returned nil.

UIImage *appIcon = [UIImage imageNamed"AppIcon"];

The app icon is named AppIcon (the default), and the actual files are app-icon-256.png etc.

I also noticed that unlike normal images, app icons are in an "App Icon" set, in the directory AppIcon.appiconset. Normal images are in the directory someimage.imageset.

samwize
  • 25,675
  • 15
  • 141
  • 186

4 Answers4

74

The problem is that the AppIcon from the asset catalog is not placed in the the catalog after compiling. Instated it it copied into your apps bundle, just like before.

The name conversion used when copying the icon to the app bundle is AppIcon<size>.png, where the size is for example 40x40 or 72x72

You can get your apps icons by specifying the size of the app icon you want:

UIImage *appIcon = [UIImage imageNamed:@"AppIcon40x40"];
rckoenes
  • 69,092
  • 8
  • 134
  • 166
  • This works, though there are only 29x29, 40x40 and 60x60 in my app bundle. If there is better way to load my 256pt app icon would great. Accepting this as the answer for now. Thanks! – samwize Apr 02 '14 at 10:40
  • Since there is no icon size 256 my best guess is to add this size as a separate image in the asset catalog. – rckoenes Apr 02 '14 at 10:45
  • How can I get specified icon if I have two icons with the same size? (iPad spotlight icon and iPhone spotlight icon are both 40x40) – Harrison Xi Nov 17 '15 at 09:25
  • I was hoping I could trick interface builder, but specify the image name (on disc name) or variations mentioned above might work. Sigh. – Jules Jul 07 '17 at 07:50
  • 22
    This no longer seems to work in iOS 10, Xcode 8, Swift. – Ryan Poolos Jul 11 '17 at 18:00
  • what about UIImageView in launch storyboard? I can't do anything programmatically in this case – user924 May 17 '19 at 20:46
  • I opened the app package and found AppIcon60x60@2x there. I tried it, and it worked. I'm guessing it may need to be something else depending on the target device. Apple installs only what's needed for the particular device now. There's also AppIcon76x76@2x~ipad, and I build for iPhone, and my project is iPhone only, so maybe this works. – Victor Engel Jul 28 '22 at 00:13
  • It's probably not safe to use any of these, though, since it's not documented, and Apple could change how the apps are delivered. Maybe just drag another copy of your icon into the assets.... – Victor Engel Jul 28 '22 at 00:14
8

The >iOS10 answer is:

Copy & paste this extension.

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

Then just call this:

Bundle.main.icon

SwiftUI:

Image(uiImage: Bundle.main.icon ?? UIImage())
Rufat Mirza
  • 1,425
  • 14
  • 20
  • 1
    This doesn't work inside previews, while https://stackoverflow.com/a/62064533/3804991 does – Viktor Sec May 29 '21 at 21:49
  • 2
    @ViktorSec Maybe, but unfortunately simply using "AppIcon" as filename will load smallest resolution of the image, while this answer loads highest resolution. – Top-Master Dec 19 '21 at 09:46
8

Update Sep 12 2022: This doesn't work anymore, as of iOS 16.0.0 at least.

The methods of loading the main app icon highlighted in other answers like from Rufat Mirza used to work, and still does for debug builds, but I got an app rejection from Apple saying the app was crashing on launch. Turns out that the builds that contained this code started crashing on iOS 16, but only when installed via App Store/TestFlight (builds using the "Release" Configuration). What's more weird is that builds using the "Release" Configuration compiled via Xcode also wouldn't crash, only when uploaded to App Store and downloaded from TestFlight, so keep this in mind.

The fix was, unfortunately, to create a new Image asset with the same content as the AppIcon asset.

Note that this workaround still works for macOS as of the 12.5.1 and whatever macOS version Apple is using when reviewing their apps as of today, but since I already had to duplicate the asset for iOS, I also used the same asset for macOS to avoid this little hack :)

Roger Oba
  • 1,292
  • 14
  • 28
  • I didn’t test uploading it to the App Store yet, but I noticed as well that this method isn’t working properly anymore (with Xcode 14 & iOS 16)! It only returns the 60pt size for me, when using the individual sizes. I can’t get it to specifically access the 1024px size. Only if I switch the app icon asset to "single size" … – alexkaessner Apr 26 '23 at 09:59
0

For those of us, who still need an obj-c version, I made a transcript of the relevant parts of the answer by Rufat Mirza:

    NSDictionary *icons = [[NSBundle mainBundle] infoDictionary][@"CFBundleIcons"];
    NSDictionary *primary = icons[@"CFBundlePrimaryIcon"];
    NSArray *files = primary[@"CFBundleIconFiles"];
    return [UIImage imageNamed: files.lastObject];
de.
  • 7,068
  • 3
  • 40
  • 69