I'm trying to achieve drag and drop on macOS with a custom type identifier to avoid collisions but it doesn't seem to work. First, here's a working example with a public and known identifier:
struct ReleaseView: View {
let id: Int
var body: some View {
GeometryReader { _ in
VStack(spacing: 16) {
Image(nsImage: NSImage(named: NSImage.networkName)!)
.contentShape(Rectangle())
.onDrag {
return NSItemProvider(item: "\(self.id)" as NSString, typeIdentifier: NSPasteboard.PasteboardType.string.rawValue)
}
DropZone()
}
}
}
}
struct DropZone: View {
@State var isDragging = false
var body: some View {
RoundedRectangle(cornerRadius: 16)
.stroke(style: StrokeStyle(lineWidth: 4, dash: [8, 8]))
.background(isDragging ? Color.secondary : Color.clear)
.frame(width: 100, height: 100)
.onDrop(of: [NSPasteboard.PasteboardType.string.rawValue], isTargeted: self.$isDragging) { itemProvider in
print(itemProvider)
return true
}
}
}
In this example, you can drag the image above into the drop zone and it will print out the provider. Now, merely changing the typeIdentifier
breaks everything.
static let sharedTypeIdentifier = "com.procrastin8.plzwork"
struct ReleaseView: View {
// skipping the unchanged bits
.onDrag {
return NSItemProvider(item: "\(self.id)" as NSString, typeIdentifier: sharedTypeIdentifier)
}
}
struct DropZone: View {
// skipping the unchanged bits
.onDrop(of: [sharedTypeIdentifier], isTargeted: self.$isDragging) { itemProvider in
print(itemProvider)
return true
}
}
Now this doesn't work. Using the same constant here, so it's not a string mismatch. Just yet another SwiftUI bug?
The typeIdentifier
in above is not just a unique string, it must be UTI.
If you want to use some custom-application-specifc UTI (think twice if you really need it), then you have to register one according to Apple rules, starting from
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.procrastin8.plzwork</string>
...
in app Info.plist
See details specifically in Declaring New Uniform Type Identifiers
And wide collection in Technical Q&A QA1796
Nowadays, you can add a type identifier through target project and it adds the UTI string automatically on the Info.plist, as explained on this Raywenderlich article.
Walkthrough
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With