How to get App Icon


Gerriet M. Denkmann
 

macOS 13.6

The app has Assets.xccassets/AppIcon and shows a nice icon in the dock.

But an NSAlert just shows a boring alert-triangle.
I want it to display the icon of my app instead.

So I did:
NSImage *myAppImage = [ [NSApplication sharedApplication] applicationIconImage ];
NSLog(@"%s myAppImage: %@", __FUNCTION__, myAppImage);

myAppImage: <NSImage 0x60000007cb40 Size={128, 128} Reps=(
"<NSCGImageSnapshotRep:0x608000461b40 cgImage=<CGImage 0x6080001c3de0>\n\t<<CGColorSpace 0x6000000a04e0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)>\n\t\twidth = 256, height = 256, bpc = 8, bpp = 32, row bytes = 1024 \n\t\tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \n\t\tis mask? No, has mask? No, has matte? No, should interpolate? Yes>"
)>

[alert setIcon: myAppImage];

And now I get an even more boring default app image (paper with 2 pencils).
I really want the nice app image as shown in the dock.

There must be a simple answer (which becomes immediately obvious once known) to this.


Gerriet.


Quincey Morris
 

On Aug 29, 2018, at 20:47 , Gerriet M. Denkmann <g@...> wrote:

There must be a simple answer (which becomes immediately obvious once known) to this.

If you want to get the actual app icon, I think the simplest way is to get the URL for your app bundle, then get the URL resource key for the icon (https://developer.apple.com/documentation/foundation/urlresourcekey/1414697-effectiveiconkey).

There’s also a NSWorkspace method to get the icon for a file.

And — I’ve never tried — you may be able to use NSDataAsset to peek into the asset catalog directly.

But I wouldn’t bother. It’s easier to add a separate copy of the actual image to an asset catalog *as an image*, and to use [NSImage imageNamed:] to get it. That puts the resolution/size under your control, and you can customize the image (e.g. sub-badging it with a caution or error icon) if you decide you need to, and it’s one line of code to get.


Jon Gotow
 

I think you may be trying too hard. NSAlert should show a badged copy of your application icon if you just leave it set to its defaults (don't set an icon at all).

- Jon

On Aug 29, 2018, at 9:47 PM, Gerriet M. Denkmann <g@...> wrote:

macOS 13.6

The app has Assets.xccassets/AppIcon and shows a nice icon in the dock.

But an NSAlert just shows a boring alert-triangle.
I want it to display the icon of my app instead.

So I did:
NSImage *myAppImage = [ [NSApplication sharedApplication] applicationIconImage ];
NSLog(@"%s myAppImage: %@", __FUNCTION__, myAppImage);

myAppImage: <NSImage 0x60000007cb40 Size={128, 128} Reps=(
"<NSCGImageSnapshotRep:0x608000461b40 cgImage=<CGImage 0x6080001c3de0>\n\t<<CGColorSpace 0x6000000a04e0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)>\n\t\twidth = 256, height = 256, bpc = 8, bpp = 32, row bytes = 1024 \n\t\tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \n\t\tis mask? No, has mask? No, has matte? No, should interpolate? Yes>"
)>

[alert setIcon: myAppImage];

And now I get an even more boring default app image (paper with 2 pencils).
I really want the nice app image as shown in the dock.

There must be a simple answer (which becomes immediately obvious once known) to this.


Gerriet.




Gerriet M. Denkmann
 

On 30 Aug 2018, at 12:21, Jon Gotow <gotow@...> wrote:

I think you may be trying too hard. NSAlert should show a badged copy of your application icon if you just leave it set to its defaults (don’t set an icon at all).
Yes it should. Also: the documentation says, it does. But sadly it does not.


- Jon


On Aug 29, 2018, at 9:47 PM, Gerriet M. Denkmann <g@...> wrote:

macOS 13.6

The app has Assets.xccassets/AppIcon and shows a nice icon in the dock.

But an NSAlert just shows a boring alert-triangle.
I want it to display the icon of my app instead.

So I did:
NSImage *myAppImage = [ [NSApplication sharedApplication] applicationIconImage ];
NSLog(@"%s myAppImage: %@", __FUNCTION__, myAppImage);

myAppImage: <NSImage 0x60000007cb40 Size={128, 128} Reps=(
"<NSCGImageSnapshotRep:0x608000461b40 cgImage=<CGImage 0x6080001c3de0>\n\t<<CGColorSpace 0x6000000a04e0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)>\n\t\twidth = 256, height = 256, bpc = 8, bpp = 32, row bytes = 1024 \n\t\tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \n\t\tis mask? No, has mask? No, has matte? No, should interpolate? Yes>"
)>

[alert setIcon: myAppImage];

And now I get an even more boring default app image (paper with 2 pencils).
I really want the nice app image as shown in the dock.

There must be a simple answer (which becomes immediately obvious once known) to this.


Gerriet.






Gerriet M. Denkmann
 

On 30 Aug 2018, at 12:13, Quincey Morris <quinceymorris@...> wrote:

On Aug 29, 2018, at 20:47 , Gerriet M. Denkmann <g@...> wrote:

There must be a simple answer (which becomes immediately obvious once known) to this.
If you want to get the actual app icon, I think the simplest way is to get the URL for your app bundle,
I failed to find this. Probably missed something obvious.

But I stumbled upon:

NSRunningApplication *currentApplication = NSRunningApplication.currentApplication;
NSImage *myAppImage = currentApplication.icon;

Which is exactly what I needed.

then get the URL resource key for the icon (https://developer.apple.com/documentation/foundation/urlresourcekey/1414697-effectiveiconkey).

There’s also a NSWorkspace method to get the icon for a file.

And — I’ve never tried — you may be able to use NSDataAsset to peek into the asset catalog directly.
Also tried this (and failed miserably):

All these just return nil:
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"AppIcon" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets.xcassets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets" bundle: NSBundle.mainBundle]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets.xcassets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @“AppIcon" bundle: NSBundle.mainBundle]; // nil

The last one writes the message:
[framework] CoreUI: attempting to lookup a named data 'AppIcon' with a type that is not a data type in the AssertCatalog

Then I gave up.

Kind regards,

Gerriet.


Alex Zavatone
 

There also should be a special size for the small alert icon within your app’s icon xcassets file.  


On Aug 30, 2018, at 12:13 AM, Quincey Morris <quinceymorris@...> wrote:

On Aug 29, 2018, at 20:47 , Gerriet M. Denkmann <g@...> wrote:

There must be a simple answer (which becomes immediately obvious once known) to this.

If you want to get the actual app icon, I think the simplest way is to get the URL for your app bundle, then get the URL resource key for the icon (https://developer.apple.com/documentation/foundation/urlresourcekey/1414697-effectiveiconkey).

There’s also a NSWorkspace method to get the icon for a file.

And — I’ve never tried — you may be able to use NSDataAsset to peek into the asset catalog directly.

But I wouldn’t bother. It’s easier to add a separate copy of the actual image to an asset catalog *as an image*, and to use [NSImage imageNamed:] to get it. That puts the resolution/size under your control, and you can customize the image (e.g. sub-badging it with a caution or error icon) if you decide you need to, and it’s one line of code to get.


Alex Zavatone
 

Are you using an assets file (xcassets) for your app icon? If you make an icon asset in an xcassets file it should contain a slot for that icon at all sizes.

On Aug 30, 2018, at 1:07 AM, Gerriet M. Denkmann <g@...> wrote:



On 30 Aug 2018, at 12:13, Quincey Morris <quinceymorris@...> wrote:

On Aug 29, 2018, at 20:47 , Gerriet M. Denkmann <g@...> wrote:

There must be a simple answer (which becomes immediately obvious once known) to this.
If you want to get the actual app icon, I think the simplest way is to get the URL for your app bundle,
I failed to find this. Probably missed something obvious.

But I stumbled upon:

NSRunningApplication *currentApplication = NSRunningApplication.currentApplication;
NSImage *myAppImage = currentApplication.icon;

Which is exactly what I needed.

then get the URL resource key for the icon (https://developer.apple.com/documentation/foundation/urlresourcekey/1414697-effectiveiconkey).

There’s also a NSWorkspace method to get the icon for a file.

And — I’ve never tried — you may be able to use NSDataAsset to peek into the asset catalog directly.
Also tried this (and failed miserably):

All these just return nil:
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"AppIcon" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets.xcassets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets" bundle: NSBundle.mainBundle]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @"Assets.xcassets" ]; // nil
//NSDataAsset *ass = [[ NSDataAsset alloc] initWithName: @“AppIcon" bundle: NSBundle.mainBundle]; // nil

The last one writes the message:
[framework] CoreUI: attempting to lookup a named data 'AppIcon' with a type that is not a data type in the AssertCatalog

Then I gave up.

Kind regards,

Gerriet.




Quincey Morris
 

On Aug 29, 2018, at 23:07 , Gerriet M. Denkmann <g@...> wrote:

But I stumbled upon:

NSRunningApplication *currentApplication = NSRunningApplication.currentApplication;
NSImage *myAppImage = currentApplication.icon;

Which is exactly what I needed.

Sounds good to me. :)


Graham Cox
 

On 30 Aug 2018, at 3:27 pm, Gerriet M. Denkmann <g@...> wrote:

Yes it should. Also: the documentation says, it does. But sadly it does not.

Well, it does.

So if yours does not, rather than go round the houses trying to figure out how to “correct” for that, why not find out why yours isn’t doing what the rest of our apps does do? Something you’re doing is preventing standard behaviour. Don’t do more, do less.

—Graham