Article

Supporting Drag and Drop for Data Sent to Final Cut Pro

Add drag and drop support so your users can drag media assets and timeline sequences from your app directly into Final Cut Pro.

Overview

Enable drag and drop in your app so your users can drag media assets (or media assets as clips) directly to the Final Cut Pro sidebar, browser, or timeline. For example, if your users frequently send small batches of individual clips to different areas in Final Cut Pro, and often go back and forth between your app and Final Cut Pro, supporting drag and drop can make that process more intuitive.

Drag and drop operations use a pasteboard as the standardized mechanism for exchanging data between apps.

Illustration showing the drag and drop movement of an FCPXML file from your app through a pasteboard  to Final Cut Pro.

When your users start dragging items from your app, it creates a promise—a commitment to provide a data representation—in the drag pasteboard. When users drop the assets into Final Cut Pro, Final Cut Pro retrieves the content of the promise, and the operating system requests the FCPXML document from your app. Your app returns the FCPXML document that represents the dragged asset.

Create a Promise in the Pasteboard

The specific steps for enabling drag and drop in your app depend on your app’s design and purpose and include tasks such as adding support to the views in your app and implementing delegate methods. For details and more explanation about the steps for enabling drag and drop, see Drag and Drop in the AppKit framework.

When your app is ready to support drag and drop, use the following code snippet to create a promise. In the drag handler, instantiate your custom item provider class that implements the NSPasteboardItemDataProvider protocol. Create a pasteboard item and set your custom item provider to it, with the payload type com.apple.finalcutpro.xml. You can then write the pasteboard item to the drag pasteboard. (For more information, see NSPasteboardItem.)

// create the item provider with the data the user dragged
YourItemProvider    *itemProvider = [[YourItemProvider alloc] initWithYourData: self.selection];
NSPasteboardItem    *item = [[NSPasteboardItem alloc] init];
    
// set the item provider to the pasteboard item for the payload type
BOOL ok = [item setDataProvider: itemProvider
                       forTypes: @[@"com.apple.finalcutpro.xml"]];
if (ok) {
    [draggingPasteboard writeObjects:[NSArray arrayWithObject: item]];
}   

Respond to Final Cut Pro and Return FCPXML

Once your user drops the dragged items into Final Cut Pro, Final Cut Pro takes over. It retrieves the data from the promise you created in the pasteboard, which invokes the NSPasteboardItemDataProvider protocol method in your app. (The method is expected to return FCPXML.)

Use the following code as a guide to implement the NSPasteboardItemDataProvider protocol method on your app’s custom pasteboard item provider class and return the FCPXML.

- (void) pasteboard:(NSPasteboard *)sender
               item:(NSPasteboardItem *)item
 provideDataForType:(NSString *)type
{
    // be sure the type matches your expected payload type
    if ([type isEqualToString:@"com.apple.finalcutpro.xml"]) {
        // build a new XML document for what the user dragged
        NSXMLDocument* xmlDoc = [self.itemData newXMLDocument];
        NSUInteger xmlOptions = NSXMLNodeCompactEmptyElement | NSXMLNodePrettyPrint;
        NSData* xmlData = [xmlDoc XMLDataWithOptions:xmlOptions];
        
        if (xmlData != nil)
            [item setData:xmlData
                  forType:type];
    }
}

Final Cut Pro validates the document type and the DTD version in the returned FCPXML, and then creates the objects it describes. If there are naming conflicts between new and existing objects, Final Cut Pro handles those conflicts according to the rules described in the following table.

When users drag a file containing:

Final Cut Pro does the following:

One or more events to a library in the Final Cut Pro sidebar

Adds the events to the library. If the library already contains an event with the same name, Final Cut Pro merges the content of the new event with the content in the existing event.

One or more clips to a Final Cut Pro timeline

Adds the clips to the event containing the project that’s open in the timeline. Final Cut Pro then inserts the clips onto the timeline at the point where the user dropped them.

One or more event items, consisting of any combination of clips and projects with their associated metadata, into an event in the Final Cut Pro sidebar or browser

Adds the items to the event. If the event already contains an item of the same type with the same name, Final Cut Pro prompts the user to either replace the existing item or keep both. (If the user chooses to keep both, Final Cut Pro creates a unique name for the incoming item by adding a numerical suffix to the item’s name.)

One or more event items to a library in the Final Cut Pro sidebar

Final Cut Pro creates an event with the name of today’s date, as in 06-25-19. If an event with that name already exists, Final Cut Pro adds a numeric suffix to create a unique name, as in 06-25-19 1, and adds the items to the event.

The type of object being dragged determines where it can be dropped. Final Cut Pro won’t accept a dragged item unless that item is allowed in the drop destination. For example, your users can drag clips into an event, but they can’t drag an event into a smart collection.

See Also

Data Sent from Your App to Final Cut Pro

Sending Media and Metadata to Final Cut Pro

Send media assets, timeline sequences, and metadata from your app to Final Cut Pro.

Sending Data Programmatically to Final Cut Pro

Manage and streamline the sending of batches of media assets and timeline sequences from your app using Apple events.

Sending Media to Final Cut Pro as It's Recorded

Designate media as a growing file to make it available to users while it’s still being recorded.