6

I am using this code in my info.plist:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>AirDrop Profile File Type</string>
        <key>LSHandlerRank</key>
        <string>Default</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.apple.customProfileUTI.customprofile</string>
        </array>
    </dict>
</array>

to declare a custom file type, going by the answer here, and have looked at the linked sample code, but couldn't follow it very well. I have a structure that I am converting to data and then sharing with airdrop, and I am trying to understand how to create a data type such that the receiving device knows to open my app to receive the data.

Can anyone clear it up a bit for me?

Answer is followed up here

ZiEiTiA
  • 275
  • 2
  • 16

1 Answers1

16

If your app defines a new file type. then you need to define that custom UTI in the UTExportedTypeDeclarations section of Info.plist.

This can be setup in Xcode on the Info tab of your app target under the Exported UTIs section or you can manually update Info.plist as shown below.

The CFBundleDocumentTypes is to declare what file types your app can open.

Here's a made up file type that happens to be a binary file with an extension of .fun.

<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.data</string>
        </array>
        <key>UTTypeDescription</key>
        <string>My Custom Binary File</string>
        <key>UTTypeIdentifier</key>
        <string>com.mycompany.myapp.myfiletype</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.filename-extension</key>
            <array>
                <string>fun</string>
            </array>
        </dict>
    </dict>
</array>

With that in place, you can also setup your CFBundleDocumentTypes so your app is offered as a choice to open such files:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array/>
        <key>CFBundleTypeName</key>
        <string>My Custom Binary File</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.mycompany.myapp.myfiletype</string>
        </array>
    </dict>
</array>

Note how the LSItemContentTypes value of CFBundleDocumentTypes must match the UTI's UTTypeIdentifier.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • so I replace .myfiletype with whatever filetype i want - does it have to be one that exists like .png or whatever I want. and for the public.filename-extension you put 'fun' - that can also be something of my choosing? – ZiEiTiA Jul 17 '17 at 22:54
  • 1
    The value `com.mycompany.myapp.myfiletype` (in both places) needs to be a unique value that you are defining. That's your custom UTI. Ensure that entire value has never been used by anyone else. This is easily done by using the "reverse domain name" approach shown in my example. What you put after "com.mycompany" is entirely up to you (and of course "mycompany" should be changed to your actual domain name). – rmaddy Jul 17 '17 at 22:58
  • ahh ok - so in the target info I need to provide an exported UTI, an imported UTI and a document type? – ZiEiTiA Jul 17 '17 at 23:02
  • You don't need an Imported UTI in this case. Use the Exported UTI's section for your own custom UTIs that your app defines. Use the Imported UTIs to define UTIs used by your app but are not specific to your app and are not provided by Apple as standard UTIs. Use the Document Types to indicate what types of files your app can open, say as an email attachment or from another app. – rmaddy Jul 17 '17 at 23:20
  • ah great thanks, I have the data as a `Data` object, how do I specifically send it over airdrop as this file type? – ZiEiTiA Jul 17 '17 at 23:24
  • Use `UIActivityViewController`. – rmaddy Jul 17 '17 at 23:26
  • This is what I'm going with `let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil) activityViewController.popoverPresentationController?.sourceView = self.view self.present(activityViewController, animated: true, completion: nil)` – ZiEiTiA Jul 17 '17 at 23:28
  • Does this automatically send it as my file type, or do I need to specify? – ZiEiTiA Jul 17 '17 at 23:35
  • You are getting into a whole new question. I suggest you wrap up this one if the info about setting up the UTI has been helpful. Then post a new question about using `UIActivityViewController` is you need help with that. – rmaddy Jul 17 '17 at 23:36
  • will do - your answer was perfect, my UTI are all set up now thanks! – ZiEiTiA Jul 17 '17 at 23:37
  • follow up [here](https://stackoverflow.com/questions/45155228/using-uiactivityviewcontroller-to-specify-file-type) – ZiEiTiA Jul 17 '17 at 23:39