What Do You Get When You Drag and Drop a PNG File From Finder Into an NSTextView?

In short: Image file drag and drop does only produce file URLs, either with security scope-able bookmarks or plain file paths.

Dragging an image file from Finder onto an NSTextView will trigger performDragOperation(_:). You get access to NSDraggingInfo there and can inspect available content. Its draggingPasteboard (shortened to pb here) contains the following data when executed on macOS 12 Monterey:

Code Value
pb.string(forType: .string) nil
pb.string(forType: .URL) nil
NSURL(from: pb) file:///.file/id=xyz123
pb.string(forType: .fileURL) file:///.file/id=xyz123
NSURL(from: pb) as URL? file:///path/to/a.png
URL(string: pb.string(
    forType: .fileURL)!)
file:///path/to/a.png

Note that the .URL and .fileURL pasteboard types were added in macOS 10.13. Before that, you had to use the NSURL.init(from:) helper, the docs say. The table shows it still works.

Also pay attention to bridging NSURL to Swift URL: this changes the file URL or security scoped bookmark URL to an absolute file path. Accessing a resource with a security scope using these won’t work, I believe. Haven’t tested that yet.

When inspecting all available pasteboard types, you get these:

> pb.types?.map { $0.rawValue }

["public.file-url",
 "CorePasteboardFlavorType 0x6675726C",
 "dyn.ah62d4rv4gu8y6y4grf0gn5xbrzw1gydcr7u1e3cytf2gn",
 "NSFilenamesPboardType",
 "dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu",
 "Apple URL pasteboard type",
 "com.apple.finder.node"])

I have no clue what the dyn.-prefixed ones are supposed to be. "NSFilenamesPboardtype" can be interesting, and "public.file-url" reveals what the .fileURL pasteboard type actually is under the hood. (You could maybe add a shim and read the file URL type even in macOS 10.12 and earlier that way – but I haven’t verified if that’s true or if dragging a file on macOS 10.12 does not actually set the "public.file-url" pasteboard type.)

Also note that pb.availableType(from: [.string, .fileContents, .html, .png, .tiff]) will be nil. You would need to use the newer .fileURL type to get a non-nil result, even though NSURL.init(from:) works.

This also shows that there’s no actual image associated witht he drag operation, which may or may not surprise you.

As a bonus, if you inspect the string values of all available types, formatted for readability, you get:

> pb.types?.map { pb.string(forType: $0) }

- public.file-url
file:///.file/id=xyz123

- CorePasteboardFlavorType 0x6675726C
file:///.file/id=xyz123

- dyn.ah62d4rv4gu8y6y4grf0gn5xbrzw1gydcr7u1e3cytf2gn
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>/path/to/a.png</string>
</array>
</plist>

- NSFilenamesPboardType
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>/path/to/a.png</string>
</array>
</plist>

- dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>file:///.file/id=xyz123</string>
    <string></string>
</array>
</plist>

- Apple URL pasteboard type
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>file:///.file/id=xyz123</string>
    <string></string>
</array>
</plist>

- com.apple.finder.node
file:///.file/id=xyz123