Creating a Custom macOS Sharing Service in Swift

In recent versions of macOS, share buttons have become a common OS feature. Everything from Finder to Safari has these buttons which use the same standardized, customizable, and extensible experience. We can easily use them in our own apps with NSSharingServicePicker, and we can even add custom services! They are similar in functionality to the iOS share sheet with UIActivityViewController.

A share button in Safari

I will demonstrate how you can use the NSSharingServicePicker yourself, and how you can add your own custom share action with NSSharingService and a corresponding delegate. The sample app (full sample code supplied at the end) adds a simple ‘Copy Text’ to clipboard option to our share menu.

Our finished product

Hook up a NSSharingServicePicker

Apple has made it remarkably easy to use this with only a few lines of code:

Explanation: First we construct a NSSharingServicePicker with an Any? array of content. In the above code, we use a single string for this as it’s all we need. Then we call show on the picker and connect the shareSheet to a button action. That’s all we need for a basic macOS share sheet!

There will be an error on the delegate line, so now we will need to adopt it.

What we have so far

Adopt the NSSharingServicePickerDelegate

We conform to NSSharingServicePickerDelegate and implement sharingServicePicker, then create our own custom service.

First I’ll share the entire code, then break it down into parts.

The delegate we adopt for NSSharingServicePicker contains this function:

sharingServicePicker(_:sharingServicesForItems:proposedSharingServices:)

It allows us to “customize exactly what appears in the sharing service picker before it is presented” and add or remove the services that are shown.

Create a Custom NSSharingService

To add our own service, we can create a custom NSSharingService with this init method which takes a title and an image:

init(title:image:alternateImage:handler:)

The important part is the handler, which allows us to customize the functionality of the share button. In our case, we will simply copy our text to the clipboard:

handler: {            
if let text = items.first as? String {
let clipboard = NSPasteboard.general
clipboard.clearContents()
clipboard.setString(text, forType: .string)
}
}

items is the Any? array we passed to NSSharingServicePicker earlier

Our custom share service

Small Adjustments

For the most part, that’s it. There are a couple of other minor things to note:

  • If you are triggering NSSharingServicePicker with a button action, you will likely get an error about actions which you can fix by setting .sendAction(on: .leftMouseDown) on the button
  • NSSharingService requires you provide an image for the sharing service, I would recommend using the xcode assets folder for this

Sample Project Source Code

If you want to see a simple sample app with this code, you can find it here

Inspiration for This Post

I am currently building a menubar macOS app for my senior project, which allows you to instantly share text or code to gist.github.com. The entirety of the code is open source on my GitHub, and can be found here.

When looking to add a simple copy to clipboard function to the share sheet, I could not find any stackoverflow questions or medium articles about this topic, so I decided to write my first article!

My app Peregrine with the custom sharing service

Thanks for reading!

Like what you read? Give Tristen Miller a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.