How to change file icon for macOS native file type?

First up, there are several other posts here and on StackOverflow and SuperUser about this, but few of the answers are satisfactory, definitive or up-to-date.

I want to change the file icon for all PostScript files on my system to this:

enter image description here

(Veteran Mac users may recognise the inspiration for my design, to which all are welcome.)

Most solutions suggest hacking the Info.plist and Resources of the application that opens the file type: in this case, Preview, and that's undesirable for several reasons - increased security around app's integrity, re-applying the fix after every update, etc.

The alternative seems to be creating a 'dummy' application, though this does not seem to be fully described. A canonic, detailed, up-to-date solution to the problem is required.

Change Icon/Thumbnail for File Type

How to change file icon based file's extension (.txt, .cpp, .docx, etc)

https://superuser.com/questions/178316/how-to-set-an-icon-for-a-file-type-on-mac

https://superuser.com/questions/1270213/macos-create-an-icon-for-all-of-one-file-type

https://stackoverflow.com/questions/28523975/change-all-file-icons-with-same-type-yosemite


Solution 1:

My solution to the problem is:

  1. Create a new application in Xcode that contains the icon resources for the file type.
  2. Select that app as the default for the file type.
  3. Substitute the app's binary inside its bundle for a hard link to the binary of the app you want to open the file.

EDIT: This only appears to work in Mojave: in Catalina, there's some code-signing fatal crash. If anyone know how to fix it...

Create a new app in Xcode

This step requires no coding whatsoever. Open a new Project as a Document-based application, using the file extension of the file type you want to change.

enter image description here

Under 'Assets.xcassets' in the sidebar, click on the + icon and under App Icons & Launch Images, select create a New MacOS Generic Icon.

enter image description here

Add the correctly sized images to the empty squares.

enter image description here

Next, in Targets > Info, define the Document Types fields with the relevant data for your file type. Select the Icon resource, and you should get the icon in the empty square.

enter image description here

You can do the same for Imported UTIs, just to cover all bases.

enter image description here

Your app should build and run without any further effort. Quit it. Back in Xcode, right-click on the app product and select "Show in Finder". Move the app to the Applications folder.

enter image description here

The LaunchServices database may not immediately update with your new app and its icons. One tip to force it to update is to copy and paste an icon into the icon square in Get Info on any file. You can delete the change immediately.

Set your app to be the default app for the file type.

This is done in the usual way in Get Info window. The Finder might not update existing windows: close and reopen to see the icon change.

enter image description here

Substitute the binary

Right-click on your new app. Select Show Package Contents. Navigate to the MacOS folder, and delete the Unix executable file inside, with the name of your app.

In another Finder window, navigate to the similar MacOS folder inside the bundle of the application that you want to open the file. (In my case, BBEdit.)

In the Terminal, type ln (that's lowercase LN) followed by a space. Then drag the Unix executable of the 'destination' app onto the Terminal window. Then drag the the empty Macos folder of your app onto the Terminal window. The completed command should look something like this:

ln /Applications/BBEdit.app/Contents/MacOS/BBEdit /Applications/PostScript.app/Contents/MacOS

Press Enter.

You should now have a hard link to the destination app (BBEdit) in your dummy app.

One important thing left to do: rename this link to the name of your app. (In my case, 'PostScript'.) You could do this in one step as part of the Terminal command above, by appending the name.

ln /Applications/BBEdit.app/Contents/MacOS/BBEdit /Applications/PostScript.app/Contents/MacOS/PostScript

Done.

As long as your dummy app and the destination app are both installed, files will display the custom icons, and launch with the app of your choice, without modifying installed apps. There doesn't seem to be any speed penalty, either.