Defining custom file types

On iOS:

When one receives a file of type .pages by email, Mail displays a large Pages icon and tapping on it opens Pages. (A long-press brings up the more complicated Actions screen).


When one receives a file of type .vcf by email, Mail displays a large Contacts icon and tapping on it opens Contacts. (A long-press brings up the more complicated Actions screen).


I have my own custom file type, .ripf, and I want to have the same behaviour because that is what my users will expect. Accordingly, in my app's Info.plist I have a CFBundleDocumentTypes dictionary providing a one-element LSItemContentTypes array referring to the name 'com.universalis.ripcard', and a UTExportedTypeDeclarations dictionary associating the UTTypeIdentifier 'com.universalis.ripcard' with a public.filename-extension 'ripf' and a public.mime-type 'text/vnd.universalis.ripcard'. All the other entries in those two dictionaries are present and correct as far as I can tell. Both CFBundleDocumentTypes[0].CFBundleTypeIconFiles and UTExportedTypeDeclarations[0].UTTypeIconFiles contain a list of icon files for the file type.


(That rather long paragraph is to avoid boring people by including the entire Info.plist!)


Some things do work.


  • .ripf files received via AirDrop bring up a suitable "Open with..." message which mentions my app, and tapping the message opens the app.
  • .ripf files received as an email attachment display as an icon. But it is the app's icon and not the icon of the file type.


BUT


Tapping on a received file's icon does not open the app, but only opens the generic Actions screen, offering Message, Mail, WhatsApp, Notes, and only then (after the user has scrolled sideways) "Copy to..." my app.


Now, the whole apparatus of CFBundleDocumentTypes and UTExportedTypeDeclarations is obscure and under-documented, and indeed the main documenation for the latter has a big warning at the top saying that it is obsolete and not being updated. That doesn't matter so much. What I need to know is:


(Less important): How do I get the right file icon?

(More important): How do I get my app to open when the icon is tapped, as Pages and Contacts do? There must be a way – unless special cases for those two apps are wired into iOS itself.

Accepted Reply

For anyone else who has this sort of problem in future, the official DTS reply is that it is impossible to get the behaviour that contacts and Pages files exhibit, whereby the icon is shown in Mail and tapping on the icon opens the relevant app. Mail is specifically programmed to handle those file types differently from others.

Replies

(That rather long paragraph is to avoid boring people by including the entire

Info.plist
!)

I hate to be the bearer of bad news but posting the actual

Info.plist
would be better in this case. Rather than posting the whole thing, edit out all the stuff that isn’t in the relevant top-level entries. Make sure to format it as code using the
<>
button.

Separate to that, the most common cause of problems like this is that folks don’t set up their UTI correctly. Make sure

com.universalis.ripcard
confirms to both
public.content
and
public.data
(or
com.apple.package
if it’s a package-based document). If you conform to just
public.content
then things kinda work but you run into problems like this one (ask me how I know)-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

You asked for it! Here are the relevant parts. After that, I have a few extra comments which may help.


<key>CFBundleDocumentTypes</key>
 <array>
  <dict>
   <key>CFBundleTypeIconFiles</key>
   <array>
    <string>rip-22x29.png</string>
    <string>rip-44x58.png</string>
    <string>ripf-64x64.png</string>
    <string>ripf-320x320.png</string>
   </array>
   <key>CFBundleTypeName</key>
   <string>RIP Card</string>
   <key>CFBundleTypeRole</key>
   <string>Editor</string>
   <key>LSHandlerRank</key>
   <string>Owner</string>
   <key>LSItemContentTypes</key>
   <array>
    <string>com.universalis.ripcard</string>
   </array>
  </dict>
 </array>
 <key>LSSupportsOpeningDocumentsInPlace</key>
 <true/>
 <key>UTExportedTypeDeclarations</key>
 <array>
  <dict>
   <key>UTTypeConformsTo</key>
   <array>
    <string>public.content</string>
    <string>public.data</string>
   </array>
   <key>UTTypeDescription</key>
   <string>RIP card</string>
   <key>UTTypeIconFiles</key>
   <array>
    <string>rip-22x29.png</string>
    <string>rip-44x58.png</string>
    <string>ripf-64x64.png</string>
    <string>ripf-320x320.png</string>
   </array>
   <key>UTTypeIdentifier</key>
   <string>com.universalis.ripcard</string>
   <key>UTTypeTagSpecification</key>
   <dict>
    <key>public.filename-extension</key>
    <array>
     <string>ripf</string>
    </array>
    <key>public.mime-type</key>
    <array>
     <string>text/vnd.universalis.ripcard</string>
    </array>
   </dict>
  </dict>
 </array>


(I have included "LSSupportsOpeningDocumentsInPlace" in case it is relevant).


I previously – by a process of trial and error – had "public.item" as the only value in UTTypeConformsTo. I have taken your suggestion and replaced it with "public.content" and "public.data", as you can see at line 30. The behaviour has changed as a result – but for the worse.

  1. In Mail, the icon has changed from the app icon to a completely generic file icon. The behaviour has not changed, in that tapping on the icon opens the activity sheet rather than the app.
  2. In Files, the icon, which was a generic file icon, still is one. But while, with "public.item", tapping on the file icon would open the app directly, with "public.content, public.data" tapping on the file icon brings up an very blank screen giving just the filename and the words "RIP card", and the user has to tap the box-with-an-arrow at the top right to get anywhere. And even then, "anywhere" isn't the app, it is the activity sheet.


When I say "worse", I’m not complaining. I am aware that sometimes it gets worse before it gets better. But I thought you ought to know!

I had a good look at your

Info.plist
setup, comparing it to an app I worked on a while back. I spotted two things of interest:
  • Your

    CFBundleTypeName
    is
    RIP Card
    , but I have it set to a UTI. I doubt this makes any difference to the OS, but a UTI makes more sense for the places where you end up using this in the doc.
  • All of your icon entries have an extension (

    .png
    ), which they shouldn’t.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Nothing like experienced eyes!


The setting of CFBundleTypeName to 'com.universalis.ripcard' sounded irrational since that made it a duplicate of LSItemContentTypes[0], but I did it anyway; and removed the ".png" suffixes too.


Unfortunately none of this has made any difference. All the behaviours I described at the bottom of the post with the 'Info.plist' extracts are exactly the same, after these changes.

Unfortunately none of this has made any difference.

Bummer. At this point I’m going to recommend that you open a DTS tech support incident so that one of my colleagues (icons are not really my métier) can look at your setup in more detail.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you, Quinn, for your help so far. I can entirely see why icons and file types aren't your métier. They are fundamentally arbitrary and non-rational. At least networking questions are founded, at some level, on reason and the laws of nature.


I do actually have a DTS incident in progress. As far as I can work out, the man completely misunderstands how file types are supposed to work, and it is quite hard to educate him. He thinks that "public.content" and "public.data" are declarations about my app, not about the file type, and that I should not be using them, whereas the first thing you told me was that I should be (as also does what Apple documentation I have managed to find).


For what it's worth, I agree with you rather than with him, but since no setting of UTTypeConformsTo makes any real difference anyway…


… anyway, you're well out of it and I will continue to enjoy reading your networking answers!

For anyone else who has this sort of problem in future, the official DTS reply is that it is impossible to get the behaviour that contacts and Pages files exhibit, whereby the icon is shown in Mail and tapping on the icon opens the relevant app. Mail is specifically programmed to handle those file types differently from others.

This thread is 4 years old now, is it still true that, "it is impossible to get the behaviour that contacts and Pages files exhibit, whereby the icon is shown in Mail and tapping on the icon opens the relevant app. Mail is specifically programmed to handle those file types differently from others." ? My app is an iOS app. Currently running Xcode 14.3 and iOS 16.4.1.