Implementing share extensions in Swift

Oluwadamisi Pikuda
4 min readApr 29, 2020

--

Get that coffee. Photo by Javier Molina on Unsplash

In this tutorial, I’ll be sharing how I implemented a media sharing functionality in my iOS application using share extensions. This functionality gives you the ability to share URLs, texts or images using the “Share” option on your iPhone. I’ll be focusing on URLs.

Share Extensions

Share extensions are from an extensive line of application extensions that Apple provides. Application extensions are used as a medium for users to communicate with your application without actually opening your app first. Share extensions, in particular, allow you to share content to your application.

In this tutorial, we will accomplish the following:

  1. Adding our application to the list of apps we can share to.
  2. Storing the shared URL in some way shape or form.
  3. Triggering application launch and utilizing the stored URL.

Alright! To begin we will set up a basic application with a TextField to hold our URL keeping a variable in the ViewController class.

It’s Share extension time!!!

Go to File -> New -> Target and select Share Extension. Make sure you link it to the main app and not your “Pods” for example.

We do not need a UI so delete “MainInterface.storyboard” and let “ShareViewController” conform to “UIViewController” instead of “SLComposeServiceViewController” removing all the default functions given. Also, remove the “NSExtensionMainStoryboard” key-value pair in the info.plist of your share extension.

Add this into the “ShareViewController” class. It closes the view on “viewDidAppear()”, which will prevent the app from seemingly freezing as there is no UI.

Deleting the storyboard leaves XCode wondering where to get your UI from so we need to add the “NSExtensionPrincipalClass” key-value pair with “ShareExtension101Share.ShareViewController” being the value. i.e. the name of your share target and the name of the class we’ll be handling the URL in.

Opening the main app

Let’s open the main app after the view is dismissed. We’ll be using URLScheme, so you will need to create your URL Scheme. But you’ll notice that “UIApplication.shared.openURL(URL)” is not available in an extension, so need to trick the system. 😈 Add this function to your ViewController.

We don’t have direct access to the “OpenURL” method from UIApplication because our share extension is not derived from one. Creating this method with the same definition as the one from UIApplication keeps the compiler happy while we dig around the responders until we find one that is derived from UIApplication and we can call the “OpenURL” method we need. To actually open the main app we will require a URL scheme to be passed into this function which we will be doing in a bit.

Handling the URL

The share extension right now is very dumb so we need to give it instructions;

1. What should it accept? (e.g. Images, text, PDFs). Which determine when your app will be available.

“NSExtensionActivationRule” in the “info.plist” currently is “TRUEPREDICATE”, which accepts everything. To streamline that to URLs we add a dictionary with the first key being “NSExtensionActivationSupportsWebURLWithMaxCount”.

Note: URLs that have just been typed/pasted will not be recognised as URLs but as text, so to carter for that we add the “NSExtensionActivationSupportsText” key.

In “viewDidAppear()” add the following;

// 1. Get the all encompasing object that holds whatever was shared. If not, dismiss view.

// 2. Check if object is a string

// 2.1 Detect URL in said string

// 2.2 Take the first URL detected

// 3. Check if the object is a URL

// 4. Dismiss view if object doesn’t contain a URL

If you run the share extension now, the URLs will be printed to console.

Note: Running the main app instead will not trigger the URLs to be printed to the console since the code is in the extension.

2. What should it do with the shared data? (URL in this case)

There are two ways to get the URL to the “TextField” on the main app that I want to cover in this post. Using URL schemes and UserDefaults.

  • URL schemes

We already have this set-up but we can do much more with it. Add this to your “AppDelegate” or “SceneDelegate” depending on how your project is setup.

Replace the print statements in “ShareViewController” with calls to inject the incoming URLs to the app’s URL and pass it to the “OpenURL” function we created earlier.

Store the URL from the URL 🤯 in a UserDefaults variable and retreive it in the “ViewController”.

You will notice that the ViewController only gets the URL when the app opens for the first time. To handle for when the application did become active we use the “ApplicationDidBecomeActive” notification.

  • UserDefaults Strictly

Here we connect the share extension directly to the main app using AppGroups and UserDefaults.

Add AppGroups to the capabilities of both the extension and main using the same app group.

Set value of “incomingURL” straight from the share extension using “.init(SuiteName” of userdefaults using the appGroup name and get it from the main app when you need it. Voila!

Now we’re done. You can find the source code here.

--

--