Receive file promises to support dragged files from other apps and provide file promises to support pasteboard operations of your app’s custom file types.
- macOS 10.14+
- Xcode 10.0+
Drag and drop on macOS uses an
NSPasteboard that is separate from the normal copy-and-paste clipboard. When dragging content that isn’t yet a file on disk at the time dragging began, apps may put a file promise onto the pasteboard instead of a file URL to avoid blocking the main thread. File promises are different from URLs because they can be read and written asynchronously at a later time, on a background queue separate from the main queue. macOS Sierra introduced modern APIs to handle file promises.
Preview the Sample App
This sample code project is a meme generator on macOS 10.14. It allows you to combine an image and text to produce a composite meme image that can be exported as a JPEG. The sample shows you how to support both file URLs and file promises when accepting images from Mail, Safari, Photos, and other apps that support drag and drop. It also demonstrates how to provide file promises to other apps.
To see this sample in action, build and run the project, then drag an image from another app or location, such as Finder, Mail, or Safari, into the app window. Dragging the image into the window imports it into a form that the sample app can parse and consume. Add text to the image by clicking on the text button in the upper-right corner and typing. Reposition the text box by dragging and dropping it within the app window. Dragging the composite image outside the app window exports it as a JPEG.
Support Image Import by Accepting File Promises
When setting up the view supporting drag and drop, register drag types provided by
NSFile. This allows the view to accept file promises that handle dragged images from Safari or Mail. The sample does this in the first view controller’s
Handle file promises before handling URLs, since the file promise generally represents the higher-quality image and should take precedence when both types are supported. Provide a background operation queue so the read and write operation doesn’t block the main thread. Until the file promise is fulfilled, show a spinner or loading indicator to give the user immediate feedback that the app is processing the drop.
Continue to handle file URLs, in case the app from which you are dragging the image doesn’t provide file promises.
Support Image Export by Providing File Promises
To write images that the app creates into formats that other apps like Safari, Mail, and Finder can consume, write an
NSFile instance to the dragging pasteboard and conform to
NSFile by implementing three delegate methods.
Use the first method to provide the title of the file. This sample uses a hard-coded string for simplicity, but depending on your use case, you should take the
file parameter into account.
Provide a background operation queue in
operation so the file reading and writing happen without blocking the app’s UI. This method is optional, but defaulting to the main queue can block your app’s UI for writing large files to disk. When possible, provide a background queue.
The third delegate method performs the actual writing of the file to disk when it is time to fulfill the file promise. Add custom logic necessary to transform the image from your app into a file format that other apps are likely to understand, such as the JPEG format that this sample uses.