I'm developing using Xcode 12.3 (12C33) on macOS 11.1 (20C69).
My application has a sidebar drawn using NSOutlineView (kind of vaguely a source list) and a main pane also drawn using NSOutlineView. The main pane's NSOutlineView's fields are drawn using SwiftUI. I'm trying to drag a data element from the sidebar into a field in the main pane's outline view.
In the sidebar NSOutlineViewDataSource, I have this function:
As you might guess, "MyEntity" is a Core Data entity. I don't think that should affect this, but I mention it just in case. The drag works. I can drag out of the application into TextEdit, and I get the object's name.
My drop target is, as mentioned earlier, a SwiftUI view:
The of: seems to work. The drag gets the little green + orb when over that field and it goes away when over other fields. The drop is giving me NSItemProvider objects for each dragged item. The problem is the NSItemProvider objects don't seem to have any registered types. Here's what I get when I drag a single item from the sidebar to the field which accepts drops:
I have tried this with a full delegate implementation where I ask the DropInfo for all the NSItemProviders with "public.text" representations. I get a list of providers. When I ask them for their "public.text", I get the same "Cannot load representation of type public.text".
• I could understand maybe dragging an NSString to the pasteboard doesn't spit out a "public.text" object. That's easy enough to handle. If I'm understanding the object properties properly, though, it doesn't have any representations. How does that happen?
• Why is my drop target lighting up if none of the NSItemProviders I get can provide the single type I say the drop target accepts? If I change it to some other type, the drop target no longer lights up, and no longer accepts the drop.
• Does anybody have any suggestions on what to try next?
My application has a sidebar drawn using NSOutlineView (kind of vaguely a source list) and a main pane also drawn using NSOutlineView. The main pane's NSOutlineView's fields are drawn using SwiftUI. I'm trying to drag a data element from the sidebar into a field in the main pane's outline view.
In the sidebar NSOutlineViewDataSource, I have this function:
Code Block func outlineView( _ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? { sidebarControllerLogger.trace("Drag operation started.") guard let workingItem = item as? MyEntity else { sidebarControllerLogger.debug("Dragging something which isn't an object! Description: \(String(describing: item), privacy: .public)") return nil } return workingItem.name! as NSString }
As you might guess, "MyEntity" is a Core Data entity. I don't think that should affect this, but I mention it just in case. The drag works. I can drag out of the application into TextEdit, and I get the object's name.
My drop target is, as mentioned earlier, a SwiftUI view:
Code Block VStack{ ForEach(fieldArray, id:\.self) { item in Text(item.name!) } } .padding(3) .onDrop(of: ["public.text"], isTargeted: nil) { providers in mainViewLogger.trace("Entered drop handler block.") for provider in providers { print("Provider found. It provides types \(String(describing: provider.registeredTypeIdentifiers))") provider.loadItem(forTypeIdentifier: "public.text", options: nil) { item, error in print("item: \(String(describing: item))") print("error: \(String(describing: error))") } } return false }
The of: seems to work. The drag gets the little green + orb when over that field and it goes away when over other fields. The drop is giving me NSItemProvider objects for each dragged item. The problem is the NSItemProvider objects don't seem to have any registered types. Here's what I get when I drag a single item from the sidebar to the field which accepts drops:
Code Block 2021-01-21 21:52:21.680925-0600 MyApp[8505:306504] [Sidebar Controller] Drag operation started. 2021-01-21 21:52:23.334928-0600 MyApp[8505:306504] [Main View] Entered drop handler block. Provider found. It provides types [] item: nil error: Optional(Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load representation of type public.text" UserInfo={NSLocalizedDescription=Cannot load representation of type public.text})
I have tried this with a full delegate implementation where I ask the DropInfo for all the NSItemProviders with "public.text" representations. I get a list of providers. When I ask them for their "public.text", I get the same "Cannot load representation of type public.text".
• I could understand maybe dragging an NSString to the pasteboard doesn't spit out a "public.text" object. That's easy enough to handle. If I'm understanding the object properties properly, though, it doesn't have any representations. How does that happen?
• Why is my drop target lighting up if none of the NSItemProviders I get can provide the single type I say the drop target accepts? If I change it to some other type, the drop target no longer lights up, and no longer accepts the drop.
• Does anybody have any suggestions on what to try next?
Further update. I tried simply ignoring the NSItemProvider objects and instead finding the drag pasteboard and reading the objects from it directly. This feels really awkward, but it works. My drag source is the same as my original post. Here is the working drop target:
This code obviously doesn't do anything with the dropped data, and it always reports an unsuccessful drop, but the draggedItems list does actually contain the dragged objects.
Code Block Swift .onDrop(of: ["public.text"], isTargeted: nil) { _ in mainViewLogger.trace("Entered drop handler block.") let dragBoard = NSPasteboard(name: .drag) guard let draggedItems = dragBoard.readObjects(forClasses: [NSString.self], options: nil) else { return false } print("Pulled \(draggedItems.count) items from the drag pasteboard: \(String(describing: draggedItems))") return false }
This code obviously doesn't do anything with the dropped data, and it always reports an unsuccessful drop, but the draggedItems list does actually contain the dragged objects.