cocoautinspasteboardnsworkspace

Get UTI of NSPasteboardTypeFileURL


NSFilenamesPboardType got deprecated on 10.14 and the suggestion is to use NSPasteboardTypeFileURL. This gives me filename as

file:///.file/id=6571367.12885025918

and NSWorkspace is unable to get UTI out of it.

How to get UTI from NSPasteboardTypeFileURL?

Old code:

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
    NSDragOperation resultingDragMask = NSDragOperationNone;
    NSPasteboard *pboard = [sender draggingPasteboard];

    if ([[pboard types] containsObject:NSFilenamesPboardType]) {
        NSArray <NSString *>*list = [pboard propertyListForType:NSFilenamesPboardType];
        NSString *firstItem = [list objectAtIndexedSubscript:0];
        NSError *error;
        NSString *UTI = [[NSWorkspace sharedWorkspace] typeOfFile:firstItem error:&error];
        if (!error) {
            if ([[NSImage imageTypes] containsObject:UTI]) {
                resultingDragMask = NSDragOperationCopy;
            }
        }

    } else if ([[pboard types] containsObject:NSPasteboardTypeTIFF]) {
        resultingDragMask = NSDragOperationCopy;
    }

    if (sourceDragMask & NSDragOperationCopy && resultingDragMask & NSDragOperationCopy) {
        return NSDragOperationCopy;
    }
    return NSDragOperationNone;
}

With NSPasteboardTypeFileURL I get error which states file doesn't exist. Dragged from pasteboard:

Printing description of error: Error Domain=NSCocoaErrorDomain Code=260 "The file “id=6571367.12885025918” couldn’t be opened because there is no such file." UserInfo={NSURL=file:/.file/id=6571367.12885025918 -- file:///Users/xxx/Library/Containers/com.xxx.imageviewfix/Data/, NSFilePath=/Users/xxx/Library/Containers/com.xxx.imageviewfix/Data/file:/.file/id=6571367.12885025918, NSUnderlyingError=0x600000c70d80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}


Solution

  • I am late to this question but I found this works:

      NSArray<Class> *classes = @[[NSURL class]];
      NSDictionary *options = @{};
      NSArray<NSURL*> *files = [pboard readObjectsForClasses:classes options:options];
    
      for (NSURL *url in files)
      {
         NSString *str = [url path];
    
         // TODO: do something with str.
      }
    

    Unlike the other answer, dropping multiple files works with this approach.