Swift 3 // Initialize a file path via drag & drop

Hey there!


I already wrote a program wich ables me to drag and drop within my view controller.

I do not understand, if I need the NSPasteboard objects to initialize a filepath in the moment, while i click the mouse on a file and start to drag it.


Am I on the right way with NSPasteboard?

Thx

Within the view controller (that is, dragging from one place to another within its view), you control exactly what format or formats you use for any data you put on the drag's pasteboard. In that context, you can also choose to use the pasteboard capabilities to "promise" data, but not supply it until it's needed, which would typically be when the drop occurs. However, that's extra work, so if you're just dragging a file whole location you already know, there's no really need to use data promises. Just provide the file data when the drag starts.


Incidentally, I would recommend you avoid putting a file path (i.e. a string) on the pasteboard, but put a URL on the pasteboard instead. URLs are generally preferred to path strings in modern apps.

Another question please:


To read the "wish directory/URL", when the user drag his file to his "wish directory":


Thx

You don't need sandboxing to drag between applications — this has been possible since before sandboxing became available.


If you're dragging files to Finder windows, you need to make sure you provide pasteboard data in a format the Finder expects. I'd start with this document:


developer.apple.com/library/content/documentation/Cocoa/Conceptual/DragandDrop/Tasks/DraggingFiles.html

Thanks, you're helping me a lot!


To a single function, I cannot translate the Dragging File Path capture to Swift 3.

All I have is this:

var filePath1: String = ""
var filePath2: String = ""

func startDrag(theEvent: NSEvent) {
    var dragImage: NSImage?
    var dragPosition: NSPoint
    
    let fileList: [Any] = [filePath1, filePath2]
    let pboard = NSPasteboard(name: NSDragPboard)
    pboard.declareTypes([NSFilenamesPboardType], owner: nil)
    pboard.setPropertyList(fileList, forType: NSFilenamesPboardType)
    
    dragImage = NSWorkspace.shared().icon(forFile: filePath1)
    dragPosition = theEvent.locationInWindow
    dragPosition.x -= 16
    dragPosition.y -= 16
    NSView.beginDraggingSession(items: [NSDraggingItem],
                                event: NSEvent,
                                source: NSDraggingSource) -> NSDraggingSession
}
func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
    let pboard: NSPasteboard? = sender.draggingPasteboard()
    if pboard?.types?.contains(NSFilenamesPboardType) {
        let files: [Any]? = pboard?.propertyList(for: NSFilenamesPboardType)
        let numberOfFiles: Int? = files?.count
        
    }
    return true
}


As you can see, I don't know, what I should hand over for the function beginDraggingSession (line 17).


After I complete the paste board part, I plan to call startDrag() outside from the view controler with:

NSEvent.addGlobalMonitorForEvents(
         matching: NSEventMask.leftMouseDown,
         handler: {(event: NSEvent) in
     
            startDrag(event: NSEvent)
         })


Thanks!

Unfortunately, the documentation I sent you to is way out of date and incomplete, and there is no good documentation provided by Apple.


The main problem you have right now is that you can't start the drag "outside" the view controller. You don't know what's outside, so you don't have a dragging source to tell you what to drag. In your above code, you're going to start a drag every time the left mouse button is pressed, which doesn't seem like a good idea.


For drags within your application, you're going to need an object that conforms to NSDraggingSource and an object that conforms to NSDraggingDestination. If you're dragging from another application, e.g. the Finder, you only need a NSDraggingDestination. The source (either inside your app or outside) is responsible for starting the drag.


It's a long time since I've implemented drag and drop, outside of a NSTableView, which does a lot of the work for you. IIRC, when you use "beginDraggingSession", you don't need to pre-fill the dragging pasteboard with items. Instead, you (in effect) pass the items as the array of NSDraggingItems. Each item, which is likely going to need to be a custom object, provides both the pasteboard object and the image that represents the object. For simple cases, like a URL and its icon, implementing this should be simple. (But of course I'm talking about drags originating inside your app.)


So, you're going to have to clarify your requirements, including exactly where you're dragging from and to.

Swift 3 // Initialize a file path via drag & drop
 
 
Q