Troubles with CFBundleDocumentTypes and photos

I'm working on adding CFBundleDocumentTypes to my Info.plist so that a user can share an image from other apps on their device and have it open inside my iPhone app.

I seem to be able to get this to work for sharing a single photo from the Photos app, but not for (1) multiple photos from the Photos app or (2) images from Safari.

One thing that makes this difficult is that my changes to Info.plist sometimes have no effect. I can remove CFBundleDocumentTypes and still see the icon, for example. Or I can add a new accepted UTI, but it has no effect. I've tried cleaning and rebuilding, deleting and reinstalling the app...no success. I tried in the simulator, too, and even Erase Content and Settings didn't force changes to be applied. I'm not sure what else to try here.

Anyway, I'd like my app to appear in the Share sheet for photo(s) from the Photos app, Mail and Safari, in particular, but really from any app that supports sharing photos.

I can share the config that seemed to work, but since changing it doesn't always have an effect, I can't guarantee that this was the one that worked. At the moment, it doesn't work, but I'm not sure why. Here it is:

<key>CFBundleDocumentTypes</key>
<array>
	<dict>
		<key>CFBundleTypeIconFiles</key>
		<array/>
		<key>CFBundleTypeName</key>
		<string>Image</string>
		<key>CFBundleTypeRole</key>
		<string>Viewer</string>
		<key>LSHandlerRank</key>
		<string>Alternate</string>
		<key>LSItemContentTypes</key>
		<array>
			<string>public.data</string>
			<string>public.jpeg</string>
			<string>public.png</string>
			<string>public.image</string>
			<string>public.gif</string>
			<string>public.url</string>
			<string>public.content</string>
		</array>
	</dict>
</array>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>

In my code, I also defined the following method in my SceneDelegate (though I think the problem is just with Info.plist):

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

Here are my questions:

  1. How do I make sure that my changes to Info.plist apply? Is there a cache somewhere that I have to force to clear? This is the trickiest part of this, because I can't reliably try an experiment and see if it worked.

  2. Adding the specific image UTI’s (public.jpeg, public.png) seemed to help, even though those types should conform to public.image, which conforms to public.data and public.content. Is it actually necessary to specify those?

  3. If the user selects multiple photos in the Photos app, my app doesn’t appear, but other third-party apps on my phone do. How can I support multiple photos?

  4. This configuration doesn't reliably show my app for Safari images - what do I need to do to make that happen?

  5. I had to use “public.data” when I briefly had Safari sharing working, but there doesn't seem to be a way to get a UTI from UIOpenURLContext. Right now, my code just tries to load the data as an image and aborts if UIImage(data:) returns nil. Is this a safe way of doing this? Is there a way to get the UTI for the data?

Answered by Engineer in 822053022

Hi,

You will need a share extension with declared data types that activate your extension.

You can read about activation rules and Share Extensions here.

Hi,

You will need a share extension with declared data types that activate your extension.

You can read about activation rules and Share Extensions here.

Thanks for the response. I'm aware of share extensions, but they appear above the sharing app and are totally separate from the main app's data. Using a share extension is going to require breaking down my code into frameworks and also finding ways to update shared data that the share extension can use from my main app.

If I can simply open the image in my app (as in the example apps I mentioned above, like Instagram, Obsidian, etc), then all of that complexity is gone.

However, it seems like CFBundleDocumentTypes (at least as I've configured it) will only achieve what I want when sharing a single photo from the Photos app. It doesn't work in Safari or Mail, or if I've selected multiple photos in the Photos app.

These other apps are able to do all of those things, and yet they switch control to the receiving app instead of just appearing over the sending app like a share extension.

How can I do the same thing?

Troubles with CFBundleDocumentTypes and photos
 
 
Q