Dragging files available in future (NSFilePromise)

While implementing drag&drop capability i was searching for a way to drag a file from a custom view without having any data to write to the current pasteboard. In fact the data has a name but no content at the moment of drag.

In iScrape I added the functionlity of dragging from the preview view to any directory in finder. When the user releases the mouse the data isn´t available yet but must be downloaded and written in the target location. Apple’s API offers a smart solution for this issue.

Main steps are:

1. Register your view as a dragging source by registering for every filetype it can provide to a drop destination. Since we don´t provide any certain data but files which will be created in future we must register for NSFilenamesPboardType.The best place to do this is init method:

[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];

2. implement two delegate methods which get called one after the other:

-(NSArray*)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination;  

– (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation (NSDragOperation)operation;

3. Initiate a drag in mouseDown: method using dragPromisedFilesofType: fromRect: source: slideBack: event: where source is the object which implements the second method in 2.

To give you an idea of how to inititate a drag here you have my mouseDown: implementation
The first delegate method gets called after the drag has dropped onto a destination that accepts NSFilenamsPboardType drops.
The sender asks you to return the filenames of  files you want to create. The sender also provides the droplocation (dropDestination) where you ended the drag or released the mouse. It couldn´t be easier to get the droplocation, but don´t forget to store it because this is the place where you´ll have to save the files…
…Later when draggedImage: endedAt: operation: get’s called: create your data (e.g. download an image from the web) and write the file to the dropLocation. I use something like this where imageURL is the stored dropLocation extended by the filename of the image.
My DownloadController synchronously loads the file from the web and stores it using the static writeFile… method. But since i use dispatch_async without any reference to other objects used in meantime, it´s a thread-safe async download.
I hopefully could help you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s