I have a drag and drop running on Mail, working for a while. This was until I upgraded to OSX 10.13.
Here is my code:
class DropView: NSView { var filePath: String? required init?(coder: NSCoder) { super.init(coder: coder) self.wantsLayer = true self.layer?.backgroundColor = NSColor.red.cgColor registerForDraggedTypes([NSPasteboard.PasteboardType .fileNameType(forPathExtension: ".eml"), NSPasteboard.PasteboardType.filePromise]) } override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { if true { self.layer?.backgroundColor = NSColor.blue.cgColor return .copy } } override func draggingExited(_ sender: NSDraggingInfo?) { self.layer?.backgroundColor = NSColor.red.cgColor } override func draggingEnded(_ sender: NSDraggingInfo) { self.layer?.backgroundColor = NSColor.gray.cgColor } override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { let pasteboard: NSPasteboard = sender.draggingPasteboard() let filePromises = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] let folderPath = NSHomeDirectory()+"/Drop Stuff/" if (!FileManager.default.fileExists(atPath: folderPath)) { do { try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil) } catch { print ("error") } } let folderURL = NSURL(fileURLWithPath: folderPath) let f = sender.namesOfPromisedFilesDropped(atDestination: folderURL as URL) print (f!) print ("Copied to \(folderPath)") return true } }
The problem is that namesOfPromizedFilesDropped returns the name of the parent folder, not the file name, as in the previous version of the OS.
The compiler warns that namesOfPromizedFilesDropped is out of date. Good work Apple for the lack of documentation on new materials. Thanks to StackOverflow, I was able to put this together, which works using the new APIs, but still demonstrates the same problem as above.
class DropView2: NSView { var filePath: String? required init?(coder: NSCoder) { super.init(coder: coder) self.wantsLayer = true self.layer?.backgroundColor = NSColor.red.cgColor registerForDraggedTypes([NSPasteboard.PasteboardType .fileNameType(forPathExtension: ".eml"), NSPasteboard.PasteboardType.filePromise]) } override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { if true { self.layer?.backgroundColor = NSColor.blue.cgColor return .copy } } override func draggingExited(_ sender: NSDraggingInfo?) { self.layer?.backgroundColor = NSColor.red.cgColor } override func draggingEnded(_ sender: NSDraggingInfo) { self.layer?.backgroundColor = NSColor.gray.cgColor } override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { let pasteboard: NSPasteboard = sender.draggingPasteboard() guard let filePromises = pasteboard.readObjects(forClasses: [NSFilePromiseReceiver.self], options: nil) as? [NSFilePromiseReceiver] else { return false } print ("Files dropped") var files = [URL]() let filePromiseGroup = DispatchGroup() let operationQueue = OperationQueue() let destURL = URL(fileURLWithPath: "/Users/andrew/Temporary", isDirectory: true) print ("Destination URL: \(destURL)") filePromises.forEach ({ filePromiseReceiver in print (filePromiseReceiver) filePromiseGroup.enter() filePromiseReceiver.receivePromisedFiles(atDestination: destURL, options: [:], operationQueue: operationQueue, reader: { (url, error) in print ("Received URL: \(url)") if let error = error { print ("Error: \(error)") } else { files.append(url) } print (filePromiseReceiver.fileNames, filePromiseReceiver.fileTypes) filePromiseGroup.leave() }) }) filePromiseGroup.notify(queue: DispatchQueue.main, execute: { print ("Files: \(files)") print ("Done") }) return true } }
I am using 10.13.2. Am I doing something wrong or is this a mistake?
It drives me crazy.
source share