< Previous PageNext Page > Hide TOC

Adopting Uniform Type Identifiers

This chapter gives some guidelines for adopting uniform type identifiers in your application, and gives an overview of the utility functions used to manipulate UTIs.

In this section:

Guidelines for UTI Usage
An Overview of UTI Functions


Guidelines for UTI Usage

Adopting UTIs in your application is a two-part process. You should use UTIs whenever you need to identify or exchange data, and you should declare specific UTIs for any proprietary types your application uses.

Adding UTI Support to Applications

Apple is building in UTI support for most data-interchange needs. For example:

If you have specific needs that are not addressed by the above, you can match types to UTIs in your own code. Typically this requires you to find a type with an alternate identifier (such as an OSType), create a UTI from that identifier, then check for conformance with UTIs defining the types your application can handle. For an example of how to do this, see Navigation Services Tasks in Navigation Services Programming Guide.

Important: When using system-defined UTIs in your code, you should use the constants defined in UTCoreTypes.h (in the Launch Services framework) when available, rather than the actual UTI strings. For example, pass kUTTypeApplication rather than “com.apple.application”. “System-Declared Uniform Type Identifiers ” lists these constants in addition to the UTI strings.

Declaring Your Own UTIs

If your application uses proprietary data formats, you should declare them in the Info.plist file of your application bundle. Some guidelines:

An Overview of UTI Functions

You can find the functions used to manipulate UTIs in UTType.h in the Launch Services framework.

Testing for Equality and Conformance

When testing to see if two UTIs are identical, you should always use the UTTypeEqual function rather than direct string comparison:

Boolean UTTypeEqual (
        CFStringRef inUTI1,
        CFStringRef inUTI2
    );

The two UTIs are equal if

However, in many cases you want to determine whether one UTI is compatible with another, in which case you should check for conformance rather than equality:

Boolean UTTypeConformsTo (
        CFStringRef inUTI1,
        CFStringRef inUTI2
    );

The UTTypeConformsTo function returns true if inUTI1 conforms to inUTI2. Conformance relationships are transitive: if A conforms to B, and B conforms to C, then A conforms to C.

Manipulating Tags

Often to use UTIs effectively, you must be able to convert various other type identifiers (OSType, MIME, and so on) to UTIs and vice versa.

To convert an identifier to a UTI, you can use the UTTypeCreatePreferredIdentifierForTag function:

CFStringRef UTTypeCreatePreferredIdentifierForTag(
        CFStringRef inTagClass,
        CFStringRef inTag,
        CFStringRef inConformingToUTI
    );

For the tag class, you pass one of the following tag class constants that define the alternate identifiers:

const CFStringRef kUTTagClassFilenameExtension;
const CFStringRef kUTTagClassMIMEType;
const CFStringRef kUTTagClassNSPboardType;
const CFStringRef kUTTagClassOSType;

You can pass a UTI in the inConformingToUTI parameter as a hint, in case the given tag appears in more than one UTI declaration. For example, if you know that the filename extension tag is associated with a file, not a directory, you can pass public.data here, which causes the function to ignore any types with the same extension that conform to public.directory. Pass NULL for this parameter if you have no hints.

In the rare case that two or more types exist that have the same identifier, this function prefers public UTIs over others. If no declared UTI exists for the identifier, UTTypeCreatePreferredIdentifierForTag creates and returns a dynamic identifier.

If you want to obtain all the UTIs that correspond to a given identifier, you can call UTTypeCreateAllIdentifiersForTag:

CFArrayRef UTTypeCreateAllIdentifiersForTag(
    CFStringRef inTagClass,
    CFStringRef inTag,
    CFStringRef inConformingToUTI );

This function returns an array of UTIs that you can examine to determine which one to use.

If you want to create an alternate identifier from a UTI, you call the UTTypeCopyPreferredTagWithClass function:

CFStringRef UTTypeCopyPreferredTagWithClass(
    CFStringRef inUTI,
    CFStringRef inTagClass );

The preferred tag is the first one listed in the tag specification array for a given tag class.

Converting OSType Identifiers

The UTI utility functions assume that all alternate identifier tags can be represented as Core Foundation strings. However, because type OSType is integer-based rather than string-based, it may not be immediately obvious how to correctly translate between type CFStringRef and type OSType. To ensure error-free encoding and decoding of OSType identifiers, use the following conversion functions:

CFStringRef UTCreateStringForOSType( OSType inOSType );
 
OSType UTGetOSTypeFromString( CFStringRef inTag );

Note: For OSType values containing only printable 7-bit ASCII characters, you can still use the CFSTR macro with a four-character string literal (for example, CFSTR("TEXT") to create a valid OSType tag.

Accessing UTI Information

To obtain a copy of a UTI’s declaration, use the UTTCopyDeclaration function:

CFDictionaryRef UTTypeCopyDeclaration(
    CFStringRef inUTI );

To obtain a URL to the bundle that contains the declaration for a given UTI, use the UTTypeCopyDeclaringBundleURL function:

CFURLRef UTTypeCopyDeclaringBundleURL(
    CFStringRef inUTI );

To obtain the localized description of a given UTI, call the UTTypeCopyDescription function:

CFStringRef UTTypeCopyDescription(
    CFStringRef inUTI );


< Previous PageNext Page > Hide TOC


© 2004, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-04-08)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.