We use URLs all the time, sometimes have to work in UTC, and occasionally stumble over UUIDs, but what is a UTI, where would you use one, and what do they have to do with metadata?
In theory, only developers, and others who enjoy life up to their neck in the alligators of macOS, should come across Apple’s Uniform Type Identifiers. But as they appear in many property lists and in the output of command tools, and are central to features such as Launch Services, it is as well to be familiar with them.
UTIs came about because of multiple systems for identifying file types in macOS. Classic Mac OS used a four-character code, the OSType, half of the Finder Info which underpinned its Desktop illusion, associating apps with documents. In that, a JPEG image file is known by the characters JPEG
, unsurprisingly. But macOS also had its origins in NeXTStep, which was essentially Unix, and believed instead in file extensions such as .jpeg
or .jpg
. Then along came MIME (or media) types, used primarily to define content types on the internet, in email messages, and so on. Under those, that JPEG image is image/jpeg
.
With three incompatible systems to choose between, Apple decided to create a fourth, the UTI. In that, the image is public.jpeg
.
UTIs are an extensive, hierarchical classification system for anything you can find stored in a computer. At the top is public.item
: every file, folder, bundle, etc., is a public.item. Then the naming gets progressively more specific: the image eventually works its way down to the most specific public.jpeg.
Apps have to declare the types of documents which they can read and write, something recorded in their property lists, which are in turn used by Launch Services to decide which app gets to open which type of document. Although this system still uses and respect OSTypes, extensions, and MIME types, it just loves a good UTI.
UTIs are also used with pasteboards, which are the basis for cut-copy-paste operations, drag and drop, Services, and a few other everyday bits of magic which apps perform with macOS.
The easiest way to see UTIs is using Terminal’s mdls
command to list metadata, as they’re counted as being (a very important) part of every file’s metadata. The command to view just the UTI hierarchy for a file named filename is
mdls -name kMDItemContentTypeTree filename
But let’s go the whole hog and view all the metadata for a text file which I have nobbled with SearchKey so that it has five extra extended attributes. This is simple using a command like
mdls 0test.txt
and produces:
_kMDItemOwnerUserID = 501
kMDItemContentCreationDate = 2017-10-26 18:47:05 +0000
kMDItemContentModificationDate = 2017-10-26 18:47:05 +0000
kMDItemContentType = "public.plain-text"
kMDItemContentTypeTree = ("public.plain-text", "public.item", "public.text", "public.data", "public.content", "public.plain-text")
kMDItemCopyright = "Copyright © 2018 EHN & DIJ Oakley"
kMDItemCreator = "Howard Oakley"
kMDItemDateAdded = 2018-01-21 20:03:00 +0000
kMDItemDescription = "This is just a test file of sorts."
kMDItemDisplayName = "0test.txt"
kMDItemFSContentChangeDate = 2017-10-26 18:47:05 +0000
kMDItemFSCreationDate = 2017-10-26 18:47:05 +0000
kMDItemFSCreatorCode = ""
kMDItemFSFinderFlags = 0
kMDItemFSHasCustomIcon = (null)
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = (null)
kMDItemFSLabel = 0
kMDItemFSName = "0test.txt"
kMDItemFSNodeCount = (null)
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 391
kMDItemFSTypeCode = ""
kMDItemHeadline = "The News Headlines 3"
kMDItemKeywords = ("key; lock; padlock; chain; safe")
kMDItemKind = "Plain Text Document"
kMDItemLastUsedDate = 2018-01-22 09:46:51 +0000
kMDItemLogicalSize = 391
kMDItemPhysicalSize = 4096
kMDItemUseCount = 45
kMDItemUsedDates = ("2018-01-21 00:00:00 +0000", "2018-01-22 00:00:00 +0000")
If you now change the extension of that file to .png
and repeat the command, you have changed some of those metadata. macOS thinks that’s a PNG image file, so the UTIs have changed to reflect that:
kMDItemContentType = "public.png"
kMDItemContentTypeTree = ("public.item", "public.png", "public.data", "public.image", "public.content")
kMDItemKind = "Portable Network Graphics image"
mdls
is one of a group of commands which work with metadata in its broadest sense. Also worth knowing are mdfind
, which searches the metadata store and returns a list of files satisfying a query, and mdutil
, which controls metadata stores on each volume, and can for example force them to be rebuilt. Those are quite complex if not awesome commands which are best left to their man
pages.
Hopefully this helps explain how file typing, metadata, Launch Services, and the amazing illusions created by macOS all hold together. If you want to read more, Apple provides a Uniform Type Identifiers Overview, and a UTI Reference with all the gory details.
Oh, and for those of you who thought that UTI stands for urinary tract infection, keep drinking plenty of fluids.