I'm trying to implement a simple drag and drop with NSString. I can get this working with NSURL but not NSString. Every time I try the drag and drop I always end up with a nil value. Here is my code:
struct ContentView: View
{
var body: some View
{
Text("Hello World")
.onDrag { NSItemProvider(object: "Hello World" as NSString) }
}
}
Then the dropped object:
struct DroppedView: View, DropDelegate
{
var body: some View
{
Text("Drop here")
.onDrop(of: ["public.text"], delegate: self)
}
func performDrop(info: DropInfo) -> Bool
{
if let items = info.itemProviders(for: ["public.text"]).first
{
item.loadItem(forTypeIdentifier: "public.text", options: nil)
{
(data, error) in
print(data)
}
}
return true
}
}
I would have expected the output to be "Hello World". What am I missing?
I don't recall where (somewhere in depth of Apple's docs) but I met occasionally that we should not use base UTTypes (like public.text) for data loading - instead only concrete types (like in this answer) must be used.
The NSString
register itself as UTF-8 plain text type provider (it conforms to public.text but cannot be decoded to), so worked variant is
func performDrop(info: DropInfo) -> Bool
{
if let item = info.itemProviders(for: ["public.utf8-plain-text"]).first
{
item.loadItem(forTypeIdentifier: "public.utf8-plain-text", options: nil)
{
(data, error) in
if let data = data as? Data {
print(NSString(data: data, encoding: 4) ?? "failed")
}
}
}
return true
}
Tested with Xcode 13 / macOS 11.5.2