http://example.com/apps/mycoolapp/icon, where a web application is returning the image data dynamically, so I can't use the extension from the filename part of the URL.
I could just save the image data in a file named "icon" with no extension, since the
UIImageclass will look at the header in the image data to determine the true image type. Neither the filename extension nor the mime type in the
Content-Typeresponse header is reliable in general, but in this case I wrote the web application that my iPhone app is talking to, so I can make sure the
Content-Typein the response is reliable.
So now all I need is a way to turn a mime type into a file extension. Rather than build my own table that maps mime types to extensions, I though there might be a way to get this from iOS. Turns out there is: Uniform Type Identifiers, which are available on both iOS and Mac OS X. On iOS, first add the MobileCoreServices framework to your project, then import the
<MobileCoreServices/MobileCoreServices.h>header. On Mac OS X, add the CoreServices framework and import
A Uniform Type Identifier (UTI) is simply a string like
com.apple.pictthat identifies a file or directory type. Proprietary formats use a reverse DNS naming scheme while common formats begin with
public. Additionally, third party developers can define UTIs for their application data formats. UTIs are typically associated with one or more file extensions and mime types. In UTI parlance, extensions and mime types are "tags".
If you have a mime type, you can get the UTI for it using the
UTTypeCreatePreferredIdentifierForTag()function. To get the UTI for
// get a UTI for a mime type CFStringRef mimeType = (CFStringRef)@"image/png"; CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); // uti now equals "public.png"Since this is a procedural API, Core Foundation memory management rules are in effect. You are the owner of the
UTTypeCreatePreferredIdentifierForTag()and are responsible for calling
CFRelease()on it. Alternately, since
CFStringRefis toll-free bridged to
NSString, you can cast the returned
NSString*and call the
Once you have the UTI, you can get the extension for it. The
UTTypeCopyPreferredTagWithClass()function takes a UTI and returns the first "tag" of the desired class (extension or mime type):
// get an extension for a UTI CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);As with
UTTypeCreatePreferredIdentifierForTag(), you own the
CFRelease()it or cast it to
You can easily reverse this process by switching the tag class constants
kUTTagClassFilenameExtensionin the examples. There's a little bit more to UTIs than I've covered here. The Uniform Type Identifiers Overview explains all the concepts behind UTIs and tags. The UTType Reference details all the functions and constants. Finally, Uniform Type Identifiers Reference lists all the system defined UTIs and their associated tags.