Fast forward to this summer - the Curalate dev team moved fast to launch Tilt to enable brands to create shoppable channels of vertical video. As a prerequisite, we wanted to make it easier for users to share images and videos with Curalate from any app by releasing an iOS share extension. We started looking for documentation about how to do this with Ionic but found that it was not supported as a first-class scenario. This is one area where Ionic doesn’t make things easier, but by sharing a guide to shipping an iOS share extension for an Ionic app we hope it’ll encourage more developers to try it.
Since Ionic doesn’t have first class support for share extensions (iOS or otherwise), we have to roll up our sleeves and delve into native platform development to get the job done. Here’s how:
1. Generate a Share Extension with XCode
The easiest way to get started is to open the .xcodeproj generated by the “ionic platform add ios” command. From XCode, follow the instructions provided by Apple here to generate the boilerplate for a simple Share extension.
2. Choose Supported Content Types
Next, edit your extension project’s .plist file to declare the types of files you want to handle. For our app we enabled sharing images and videos using the following config:
3. Share Authentication with your App
We require users to be authenticated with their Curalate account before they upload. We used iOS keychain sharing (described here) by wrapping what we learned from this StackOverflow post in a Cordova plugin. Whenever a user logs in or out of the Curalate mobile app we update the information securely stored in iOS keychain, then retrieve that information when our iOS share extension is launched.
4. Create an App Group
Images and videos can be quite large, so supporting background upload was a priority for us. Per documentation here, iOS has a restriction that background uploads must create a shared container - here’s how.
5. Upload All-The-Things
Now that you’ve got an App Group and you’ve retrieved auth information from Keychain Sharing, let’s upload the files that your user wants to share - here’s the relevant excerpt from the code we used to configure the background upload:
With that your upload is underway!
In our initial testing we noticed some flakiness in uploads completing, and eventually sourced the issue back to the fact that we needed to implement handleEventsForBackgroundSession within our app. You don’t have to do anything special, just add this to your AppDelegate.m.
Optimize Your Development Workflow
All of this is great, until you re-run “ionic platform add ios” and and it blows away all of the things you’ve just configured in XCode :( We haven’t found a good way to auto generate this stuff yet, so for the time being we’re checking in our iOS extension code and manually enabling the app group and keychain sharing capabilities whenever we need to re-add the iOS platform.
That said, we looked for a few solutions that didn’t ultimately pan out, these included:
- Declaring the iOS app capabilities in Cordova’s config.xml or similar, namely:
- Push Notifications
- Keychain Sharing
- App Groups
- Configuring Ionic/Cordova to reference existing code for our iOS extension. Unfortunately the .xcodeproj structure contains a lot of generated interlinked keys that prevented us from going this route.
- Using the Xcodeproj CocoaPod to generate our iOS extension from checked in source files. This looked promising, but ddoesn’t support Share extensions.
We’re continually looking for improvements to our development process, and will post updates here for any that we find!