How to open any file with a Swift macOS app

Problem A macOS app built in Swift (using XCode) shall show up in the "Open With" context menu for any file. But it does not show up at all.

Current status The app has a document type for public.item defined.

	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeName</key>
			<string>Any file</string>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>LSHandlerRank</key>
			<string>Default</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>public.item</string>
			</array>
			<key>NSDocumentClass</key>
			<string>NSDocument</string>
		</dict>
	</array>

When I start the app (from XCode), no file has my app in the "Open With" menu. I've seen a lot of tutorials on how to add a custom type. But not any tutorial for a public type. Is this even possible?

Actual question: How can I configure a Swift app to show up in the "Open With" menu for any file?

Answered by DTS Engineer in 765600022

Hi,

The first issue here is that you've misunderstood what "Open With" actually does. It does NOT show you "all of the applications that can open this type", but instead shows you the applications that are declared to "match" that UTI. In other words, it shows you the "narrowest" match it can, NOT the widest.

Making this concrete, do the following:

-Create an empty file with no extension (in Terminal "touch foo").

-If you check "Open With", it will list "TextEdit", "XCode", and a number of other apps. The common factor on all of them is that they declare support for "public.data", which is the "generic" type for files.

-Give the file an arbitrary file extension that ISN'T defined by any app on the system ("foo.asdfsdagtwesarfsdv").

-Check "Open With" again, and you'll see the list is unchanged. LaunchServices doesn't know what that extension means, so it falls back to "public.data".

-Change the file to "foo.pdf".

-The list will change completely. "TextEdit" and "Xcode" are gone, "Preview" and "Books.app" have appeared. However, depending on what installed some app may still appear (for example, on my machine "Hex Fiend" appears in all of these cases).

The issue here is that ".pdf" maps to "com.adobe.pdf", which "TextEdit" and "Xcode" do NOT declare support for (but "HexFiend" does).

-Do "Get Info" on "foo.pdf", open the "Open With" pop up menu, select "Other" from the bottom of the menu, and then navigate to your "Applications" directory. The default view there shows you "all" the apps that support that UTI, EVEN apps that weren't in the original "Open With" popup- so "Preview" and "Books" are enabled, but so are "TextEdit", "XCode", etc. That's because "com.adobe.pdf" eventually inherits from "public.data".

Quick side note here on a possible secondary issue. You declared "public.item", but I don't know how that will actually behave, as "public.data" is the more common "base".

With all that background, let me return to you original question:

"How can I configure a Swift app to show up in the "Open With" menu for any file?"

Basically, the more UTIs you add, the more files you'll show up "with". Whether or not that's correct depends on what you're app is actually doing but, for example, BBEdit shows up fairly "broadly" and that's because it's listed itself for 100+ UTIs.

-Kevin Elliott, DTS Engineer, CoreOS/Hardware

did you have a look at what other apps which can open any file are using? For example, Atom, BBEdit or HexFiend?

Accepted Answer

Hi,

The first issue here is that you've misunderstood what "Open With" actually does. It does NOT show you "all of the applications that can open this type", but instead shows you the applications that are declared to "match" that UTI. In other words, it shows you the "narrowest" match it can, NOT the widest.

Making this concrete, do the following:

-Create an empty file with no extension (in Terminal "touch foo").

-If you check "Open With", it will list "TextEdit", "XCode", and a number of other apps. The common factor on all of them is that they declare support for "public.data", which is the "generic" type for files.

-Give the file an arbitrary file extension that ISN'T defined by any app on the system ("foo.asdfsdagtwesarfsdv").

-Check "Open With" again, and you'll see the list is unchanged. LaunchServices doesn't know what that extension means, so it falls back to "public.data".

-Change the file to "foo.pdf".

-The list will change completely. "TextEdit" and "Xcode" are gone, "Preview" and "Books.app" have appeared. However, depending on what installed some app may still appear (for example, on my machine "Hex Fiend" appears in all of these cases).

The issue here is that ".pdf" maps to "com.adobe.pdf", which "TextEdit" and "Xcode" do NOT declare support for (but "HexFiend" does).

-Do "Get Info" on "foo.pdf", open the "Open With" pop up menu, select "Other" from the bottom of the menu, and then navigate to your "Applications" directory. The default view there shows you "all" the apps that support that UTI, EVEN apps that weren't in the original "Open With" popup- so "Preview" and "Books" are enabled, but so are "TextEdit", "XCode", etc. That's because "com.adobe.pdf" eventually inherits from "public.data".

Quick side note here on a possible secondary issue. You declared "public.item", but I don't know how that will actually behave, as "public.data" is the more common "base".

With all that background, let me return to you original question:

"How can I configure a Swift app to show up in the "Open With" menu for any file?"

Basically, the more UTIs you add, the more files you'll show up "with". Whether or not that's correct depends on what you're app is actually doing but, for example, BBEdit shows up fairly "broadly" and that's because it's listed itself for 100+ UTIs.

-Kevin Elliott, DTS Engineer, CoreOS/Hardware

Hi Kevin, you are right. I misunderstood how this works. Given your explanation that it shows the "narrowest" match, and not the "widest" explains the behaviour that I have seen. Thank you so much for the information.

How to open any file with a Swift macOS app
 
 
Q