By Mihai Damian


2010-05-05 14:59:22 8 Comments

On the subject of associating your iPhone app with file types.

In this informative question I learned that apps could be associated with custom URL protocols.

That was almost one year ago and since then Apple introduced 'Document Support' which goes a step further and allows apps to associate with file types. There is a lot of talk in the documentation about how to set up your app to launch other appropriate apps when it encounters an unknown file type. This means the association doesn't work out of the box for any app, like the URL protocol registering did.

This leads me to the question: have system apps like Safari or Mail implemented this system for choosing associated applications, or will they do nothing, as before?

3 comments

@mvds 2011-06-26 12:31:17

In addition to Brad's excellent answer, I have found out that (on iOS 4.2.1 at least) when opening custom files from the Mail app, your app is not fired or notified if the attachment has been opened before. The "open with…" popup appears, but just does nothing.

This seems to be fixed by (re)moving the file from the Inbox directory. A safe approach seems to be to both (re)move the file as it is opened (in -(BOOL)application:openURL:sourceApplication:annotation:) as well as going through the Documents/Inbox directory, removing all items, e.g. in applicationDidBecomeActive:. That last catch-all may be needed to get the app in a clean state again, in case a previous import causes a crash or is interrupted.

@memmons 2011-10-10 19:00:49

I don't see this behavior. If my app is backgrounded, -(BOOL)application:openURL:sourceApplication:annotation: is always called, even for attachments that have been already opened. Each additional time the attachment is opened, a number is suffixed to the filename and is incremented to be unique -- test.text, test-1.txt, test-2.txt, etc.

@Bram 2013-10-31 23:52:55

My Inbox directory is empty, but yet I have the unresponsive "Open In" button in Safari you speak of. Years ago, my app was working fine, but suddenly it stopped working. I suspect Apple changed something in Safari.

@Kalle 2013-05-24 17:57:11

BIG WARNING: Make ONE HUNDRED PERCENT sure that your extension is not already tied to some mime type.

We used the extension '.icz' for our custom files for, basically, ever, and Safari just never would let you open them saying "Safari cannot open this file." no matter what we did or tried with the UT stuff above.

Eventually I realized that there are some UT* C functions you can use to explore various things, and while .icz gives the right answer (our app):

In app did load at top, just do this...

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, 
                                                                   (CFStringRef)@"icz", 
                                                                   NULL);
CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

and put break after that line and see what UTI and ur are -- in our case, it was our identifier as we wanted), and the bundle url (ur) was pointing to our app's folder.

But the MIME type that Dropbox gives us back for our link, which you can check by doing e.g.

$ curl -D headers THEURLGOESHERE > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27393  100 27393    0     0  24983      0  0:00:01  0:00:01 --:--:-- 28926
$ cat headers
HTTP/1.1 200 OK
accept-ranges: bytes
cache-control: max-age=0
content-disposition: attachment; filename="123.icz"
Content-Type: text/calendar
Date: Fri, 24 May 2013 17:41:28 GMT
etag: 872926d
pragma: public
Server: nginx
x-dropbox-request-id: 13bd327248d90fde
X-RequestId: bf9adc56934eff0bfb68a01d526eba1f
x-server-response-time: 379
Content-Length: 27393
Connection: keep-alive

The Content-Type is what we want. Dropbox claims this is a text/calendar entry. Great. But in my case, I've ALREADY TRIED PUTTING text/calendar into my app's mime types, and it still doesn't work. Instead, when I try to get the UTI and bundle url for the text/calendar mimetype,

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
                                                                   (CFStringRef)@"text/calendar", 
                                                                   NULL);

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

I see "com.apple.ical.ics" as the UTI and ".../MobileCoreTypes.bundle/" as the bundle URL. Not our app, but Apple. So I try putting com.apple.ical.ics into the LSItemContentTypes alongside my own, and into UTConformsTo in the export, but no go.

So basically, if Apple thinks they want to at some point handle some form of file type (that could be created 10 years after your app is live, mind you), you will have to change extension cause they'll simply not let you handle the file type.

@RockSolid 2016-04-16 16:29:11

Thanks for the useful warning!

@Brad Larson 2010-05-06 13:05:35

File type handling is new with iPhone OS 3.2, and is different than the already-existing custom URL schemes. You can register your application to handle particular document types, and any application that uses a document controller can hand off processing of these documents to your own application.

For example, my application Molecules (for which the source code is available) handles the .pdb and .pdb.gz file types, if received via email or in another supported application.

To register support, you will need to have something like the following in your Info.plist:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array>
            <string>Document-molecules-320.png</string>
            <string>Document-molecules-64.png</string>
        </array>
        <key>CFBundleTypeName</key>
        <string>Molecules Structure File</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.sunsetlakesoftware.molecules.pdb</string>
            <string>org.gnu.gnu-zip-archive</string>
        </array>
    </dict>
</array>

Two images are provided that will be used as icons for the supported types in Mail and other applications capable of showing documents. The LSItemContentTypes key lets you provide an array of Uniform Type Identifiers (UTIs) that your application can open. For a list of system-defined UTIs, see Apple's Uniform Type Identifiers Reference. Even more detail on UTIs can be found in Apple's Uniform Type Identifiers Overview. Those guides reside in the Mac developer center, because this capability has been ported across from the Mac.

One of the UTIs used in the above example was system-defined, but the other was an application-specific UTI. The application-specific UTI will need to be exported so that other applications on the system can be made aware of it. To do this, you would add a section to your Info.plist like the following:

<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.plain-text</string>
            <string>public.text</string>
        </array>
        <key>UTTypeDescription</key>
        <string>Molecules Structure File</string>
        <key>UTTypeIdentifier</key>
        <string>com.sunsetlakesoftware.molecules.pdb</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.filename-extension</key>
            <string>pdb</string>
            <key>public.mime-type</key>
            <string>chemical/x-pdb</string>
        </dict>
    </dict>
</array>

This particular example exports the com.sunsetlakesoftware.molecules.pdb UTI with the .pdb file extension, corresponding to the MIME type chemical/x-pdb.

With this in place, your application will be able to handle documents attached to emails or from other applications on the system. In Mail, you can tap-and-hold to bring up a list of applications that can open a particular attachment.

When the attachment is opened, your application will be started and you will need to handle the processing of this file in your -application:didFinishLaunchingWithOptions: application delegate method. It appears that files loaded in this manner from Mail are copied into your application's Documents directory under a subdirectory corresponding to what email box they arrived in. You can get the URL for this file within the application delegate method using code like the following:

NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];

Note that this is the same approach we used for handling custom URL schemes. You can separate the file URLs from others by using code like the following:

if ([url isFileURL])
{
    // Handle file being passed in
}
else
{
    // Handle custom URL scheme
}

@HyLian 2010-07-12 13:12:27

I'm not able to try this on the iPad/iPhone simulator. I have downloaded the molecules application and Safari cannot open .pdb or even .gz files as the Info.plist claims. It simply says, "Safari cannot download the file"

@Brad Larson 2010-07-13 15:13:47

@HyLian - Yes, there is a bug in the application involving how it downloads PDBs located on certain servers that I haven't quite tracked down yet. That is independent of the file handling and custom URL schemes, though.

@Ron Srebro 2010-09-16 01:05:04

@Brad - Excellent answer - thank you. I followed your instruction as I'm trying to register an application that will open png and jpeg files, alas I couldn't get mail to show an open in... option for these attachment in mail. Is it possible to take the same approach and have mail open images in my app?

@Warrior 2010-09-22 11:15:15

@Brad Larson--> i will get the url of pdf file.I want to save the pdf file to documents directory.How can i do that?

@Brad Larson 2010-09-22 14:26:11

@Warrior - All you need to do is move the file at the URL that has been passed in to your application's Documents directory. I believe that it is automatically copied to a subdirectory in your Documents directory anyway, so you just need to move it to the root of the Documents directory and delete the old temporary subdirectory. I do this in my Molecules application, so you can look at the code I use for this.

@Brad Larson 2010-09-30 17:43:36

@nacho4d - Did you change the UTI in both places? Did you remove the org.gnu.gnu-zip-archive UTI? Did you change the UTTypeConformsTo to match that for a property list? Did you change the extension and MIME type? All of that needs to be customized for your particular case, and all references to the items I have in there need to be removed. The best reference for this are the two articles I link to above.

@nacho4d 2010-10-01 12:46:06

@Brad Thanks, I actually could do it after reading "iPad development for iPhone developers" and my answer plist is here: stackoverflow.com/questions/3827558/…

@nacho4d 2010-10-08 17:32:26

I just realized that when I attach my .mndl file to a mail using MFMailComposeViewController the attachment does not show the icon it's supposed to inside this MFMailComposerViewController, but it shows correctly in Mail.app. Is this because I didn't wrote the mime type in UTTypeTagSpecification array? If yes, what should I write? (.mndl files are a particular case of .plist I have created.) I would appreciate your help. Thanks

@memmons 2011-10-10 18:32:32

It should be noted that -application:didFinishLaunchingWithOptions: in the app delegate is only called if your app was not backgrounded when it's opened to handle a file.

@Dan Rosenstark 2012-01-07 15:59:13

Instructions work perfectly, but: How do you avoid Mail wanting to open attachments for your app in QuickLook? stackoverflow.com/q/8764525/8047

@TheLearner 2012-01-19 16:14:25

Avoiding QuickLook: raywenderlich.com/1980/…

@Brodie 2012-02-28 14:50:51

brad do you mind looking at: stackoverflow.com/questions/9434574/… I'm having a lot of trouble understanding what to put for the public.mime-type key

@fishinear 2012-10-08 21:58:40

To disable the QuickLook in Mail, set the UTTypeConformsTo to an array with a single "public/data" element.

@Dmitry 2013-02-18 02:59:50

We should use - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url also on iOS 4+

@Maulik 2013-10-17 11:35:54

@BradLarson: Hi any success with Image type file? I've tried stackoverflow.com/questions/9197757/… but didn't worked. My app doesn't show in list from Image Gallery !

@Bram 2013-10-31 23:09:26

What about the key 'CFBundleTypeExtensions'? Your snippet does not seem to set it. Is it not required?

@Kumar Aditya 2013-12-30 10:53:41

I have tried all the methodology provided here and other places as well, but I am still struggling to get open PNG files. I am working with iOS 7. In some places they are saying that this problem starts with ios 6. Is it true? Can't we open png files in "Open in " dialog box with ios 7?

@Stan James 2014-07-31 22:04:52

Be sure to check which plist file your app is using, so that your edits take effect. In Xcode, go to TargetsBuild SettingsInfo.plist File to determine which file to edit.

Related Questions

Sponsored Content

32 Answered Questions

[SOLVED] Can I embed a custom font in an iPhone application?

  • 2008-12-11 20:21:11
  • Airsource Ltd
  • 234689 View
  • 768 Score
  • 32 Answer
  • Tags:   ios cocoa-touch fonts

18 Answered Questions

[SOLVED] How to programmatically send SMS on the iPhone?

40 Answered Questions

[SOLVED] How can I develop for iPhone using a Windows development machine?

  • 2008-08-22 13:35:01
  • ryan
  • 1093812 View
  • 1144 Score
  • 40 Answer
  • Tags:   ios iphone windows

26 Answered Questions

[SOLVED] How do I sort an NSMutableArray with custom objects in it?

41 Answered Questions

[SOLVED] How to check for an active Internet connection on iOS or macOS?

36 Answered Questions

[SOLVED] How can I disable the UITableView selection?

10 Answered Questions

3 Answered Questions

[SOLVED] iPhone: redirect to app store on mobile safari if app is not installed

  • 2011-04-15 16:49:48
  • randombits
  • 23491 View
  • 9 Score
  • 3 Answer
  • Tags:   iphone ios

3 Answered Questions

[SOLVED] How to associate iPhone application with _every_ file type?

1 Answered Questions

[SOLVED] printing application for iPhone

Sponsored Content