I've been struggling with the new NSPasteboard APIs as well. The lack of sample code is appalling. I finally got file promises to work by incorporating some low level pasteboard manager calls. Note that NSPasteboard is not toll-free bridged with PasteboardRef, but you can go back & forth between the two worlds via the pasteboard name. Also note there is a warning on the console about no HFSPromises on the pasteboard, but the drag & drop works anyway. Hopefully all this will still work in the App Sandbox.
// ... write file URL promise to the pasteboard ImageObjectPasteboardItem *item = [ImageObjectPasteboardItem itemWithImageObject:imageObject]; [item setDataProvider:self forTypes:[NSArray arrayWithObject:(NSString *)kPasteboardTypeFileURLPromise]]; [item setString:(NSString *)kUTTypeImage forType:(NSString *)kPasteboardTypeFilePromiseContent]; [pasteboard writeObjects:[NSArray arrayWithObject:item]]; // ... provide promised file URL - (void)pasteboard:(NSPasteboard *)pasteboard item:(ImageObjectPasteboardItem *)item provideDataForType:(NSString *)type { if ([type isEqualToString:(NSString *)kPasteboardTypeFileURLPromise]) { // get paste location from low level pasteboard PasteboardRef pboardRef = NULL; PasteboardCreate((__bridge CFStringRef)[pasteboard name], &pboardRef); if (pboardRef != NULL) { PasteboardSynchronize(pboardRef); CFURLRef urlRef = NULL; PasteboardCopyPasteLocation(pboardRef, &urlRef); if (urlRef != NULL) { // create file at drop location NSString *folderPath = [(__bridge NSURL *)urlRef path]; ImageObject *imageObject = [item imageObject]; NSString *path = [imageObject writeToFileInFolder:folderPath]; // set UTF-8 encoded file URL for promise data NSURL *fileURL = [NSURL fileURLWithPath:path isDirectory:NO]; [item setString:[fileURL absoluteString] forType:(NSString *)kPasteboardTypeFileURLPromise]; // clean up CFRelease(urlRef); } CFRelease(pboardRef); } } } // ... read file URL promise from the pasteboard NSArray *items = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSPasteboardItem class]] options:nil]; for (NSPasteboardItem *item in items) { // we only want image files NSString *uti = [item stringForType:(NSString *)kPasteboardTypeFilePromiseContent]; if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypeImage)) { // set paste location via low level pasteboard PasteboardRef pboardRef = NULL; PasteboardCreate((__bridge CFStringRef)[pasteboard name], &pboardRef); if (pboardRef != NULL) { PasteboardSynchronize(pboardRef); PasteboardSetPasteLocation(pboardRef, (__bridge CFURLRef)[NSURL fileURLWithPath:m_addedGraphicsPath isDirectory:YES]); // ask sender to create file at destination & return UTF-8 encoded URL NSString *urlString = [item stringForType:(NSString *)kPasteboardTypeFileURLPromise]; if (urlString != nil) { NSURL *fileURL = [NSURL URLWithString:urlString]; NSString *filePath = [fileURL path]; // ... do something with filePath } CFRelease(pboardRef); } } } On Aug 12, 2011, at 11:42 AM, Gabriele de Simone <subscri...@noiseindustries.com> wrote: > Date: Fri, 12 Aug 2011 17:55:46 +0200 > From: Gabriele de Simone <subscri...@noiseindustries.com> > Subject: NSPasteboardItem kPasteboardTypeFileURLPromise > To: cocoa-dev@lists.apple.com > Message-ID: <942f5e42-d2cf-4d8d-bc39-a1542606b...@noiseindustries.com> > Content-Type: text/plain; charset=us-ascii > > Hi everyone, > > I am trying to implement "promise" type file drags from my app to the Finder > using the new, 10.6-and-later NSPasteboardItem APIs. I found almost no > information about it, and it didn't seem to make sense. > > It starts in the outlineView:writeItems:toPasteboard: method of my > NSOutlineViewDataSource instance. In there, I allocate various > NSPasteboardItems for all files being dragged. > > [...] > > NSArray * pasteboardTypes = [NSArray arrayWithObjects: > (NSString *)kPasteboardTypeFileURLPromise, > (NSString *)kPasteboardTypeFilePromiseContent, nil]; > NSMutableArray * pasteboardItems = [NSMutableArray array]; > > for ( <however many files are selected> ) { > > NSPasteboardItem * pasteboardItem = [[[NSPasteboardItem alloc] init] > autorelease]; > > [pasteboardItem setDataProvider:provider forTypes:pasteboardTypes]; > [pasteboardItems addObject:pasteboardItem]; > > } > > [pasteboard writeObjects:pasteboardItems]; > > [...] > > As the drag moves away from my application and over the Desktop, the > "provider" instance used above is called once for each NSPasteboardItem, to > get the kPasteboardTypeFilePromiseContent. That part is (presumably) easy, > and my provider is returning the UTI for the promised file, based on its > contents. In the source code below, I have inserted kUTTypePNG to simplify: > > - (void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item > provideDataForType:(NSString *)type { > > if ( [type isEqualToString:(NSString *)kPasteboardTypeFilePromiseContent] ) > { > > [item setPropertyList:kUTTypePNG forType:type]; > > } else if ( [type isEqualToString:(NSString > *)kPasteboardTypeFileURLPromise] ) { > > // What to do here? > > } > > } > > The Finder seems happy with my UTI, and allows the drag to continue. The > problem is that if I drop the files onto the desktop, the > NSPasteboardDataProvider instance is called again, this time to get the > kPasteboardTypeFileURLPromise data. > > Intuitively, one would think that you have to: > - Create the file that was promised, and keep the URL to that file handy. > - Call one of the methods on NSPasteboardItem to supply the URL of the > promised file. > - Allow the Finder to copy/move the files at will. > > Unfortunately, there is no -[NSPasteboardItem setURL:forType:] method, no > -[NSURL writeToPasteboardItem:] method, or anything else that would seem to > "fit" this scenario. > > What am I missing? > > Thanks, > Gabe _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com