codingFriend1
codingFriend1

Reputation: 6817

Where do UTI come from?

I've read a lot of blog posts and SO-questions about Uniform Type Identifiers and how OS X handles file types. However, there are still some things I just don't get:

Upvotes: 9

Views: 2712

Answers (2)

Aviris
Aviris

Reputation: 11

RE: Is it correct that there is no API to manually add or change a UTI for a specific file?

This is true, but I thought I'd share a workaround that worked for me at least.

After dumping the Launch Services db with lsregister (Thank you Becca!), I found that there was an entry for Delta emulator (which I had never heard of, let alone installed).

kLSBundleClassRemotePlaceholder container:

path:/Users/me/Library/Daemon Containers/8AEC3BAD-7322-4A5D-BFC5-B3C0BCA7E67E/Data/Library/Caches/Placeholders-v2.noindex/com.rileytestut.Delta-1.6.10/Delta.app (0x10834)

Long story short, I went and deleted the folder from the Daemon Containers folder, then killed the Launch Services register:

lsregister -kill

It took about 3 minutes, but suddenly .md files are correctly recognized as Markdown and Quicklook works and I can set the default program to Marked.

So, while there isn't an API, if you look through the lsregister -dump output you should be able to find where the UTI is being set for Finder. Whether you can fix it like I did, not sure.

In my case, mdls for .md and .mdown files was the same: Markdown Text, and I did not have any actual Genesis game files (or Delta emulator). It appears that installing VSCodium is what inserted the placeholder in the Launch Services db.


Background if you're interested

I know this is an old topic, but UTI and filetype problems with macOS (and iOS/iPadOS) are alive and kicking in 2024. My bare metal re-install of macOS 14.3 (Sequoia) was going well until I discovered Quicklook wasn't working on my thousands of Markdown documents (.md).

Finder suddenly identified .md files as Genesis game files. Since I'd run Sequoia since 14.0 on this same machine without issue I couldn't figure it out.

MDLS showed the EXACT SAME information for files with .md and .mdown, but Finder refused to recognize .md as anything but Geneses game files, which are binary, so even trying to tell it to Open with... won't work (even selecting All Programs won't allow me to select Marked or Bear etc.).

Upvotes: 1

Becca Royal-Gordon
Becca Royal-Gordon

Reputation: 17871

There's actually not that much magic to it. You've asked several different questions, so I'll try to give you each of the answers:

How are UTIs created by the system for each file?

Launch Services maintains a database of all applications (and certain other types of bundles) on your Mac and relevant information declared in their Info.plist files. It updates this information automatically—I think it has a daemon monitor the file system to watch for changes to applications, but I don't know the details. What I do know is that you can ask a tool called lsregister to dump the entire database for you. In Terminal on Mountain Lion:

$ /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump

The various UTType functions also access this Launch Services database (although I'm not sure if they do it directly or if they communicate with some kind of daemon that does it for them).

Where are UTIs stored on the file system level?

Well, the actual Launch Services database seems to be located somewhere different on each Mac. On mine, it appears to be at /private/var/folders/mf/1xd7vlw90dj5p4z1r5f800bc000101/C/com.apple.LaunchServices-0371025.csstore. (At least, lsregister holds this file open while it's working; I'm not actually sure what's in it, but I assume it's the database.)

This is just a list of the declared UTIs, though. There is no UTI field attached to a given file. When you ask Cocoa for a file's UTI—through, say, -[NSWorkspace typeOfFile:error:] or -[NSURL getResourceValue:forKey:error:]—it actually extracts the path extension from the file name and then calls UTTypeCreatePreferredIdentifierForTag() to fetch the relevant UTI. (It's a little more complicated than that, because it's also looking at things like whether the path leads to a directory or device file or something, but that's the basic idea.)

Does that imply that the UTI is stored along the Spotlight meta data? What if Spotlight is turned off?

Spotlight does keep UTIs of files in its database, but that's just so it can quickly search and filter by type. Like everything else in the Spotlight index, this information is not canonical; it's just used to quickly search data that's actually stored elsewhere. If you turn off Spotlight, that's fine—nothing else depends on it.

Is it correct that there is no API to manually add or change a UTI for a specific file?

Yes, because that UTI is calculated at runtime from other information about the file. Changing a file's UTI makes about as much sense as changing the length of its name—you can't do it without changing the name itself.

Upvotes: 26

Related Questions