如何在 macOS 上的 SwiftUI 中实现拖放至第三方应用程序

How to implement drag and drop to 3rd party apps in SwiftUI on macOS

我已经尝试 Google 寻找答案,但我发现的只是如何接受来自其他应用程序的拖放以及如何在单个应用程序中拖放,也主要是 iOS 重点,macOS相关资源不多

我正在编写一个 macOS 工具栏应用程序,我正在尝试为该应用程序以编程方式创建的图像实现拖放,并且仅在内存中作为 NSImage。为了允许图像可拖动,我实现了一个 DraggableImage 结构,用于代替 SwiftUI 视图中的 Image 视图:

struct DraggableImage: View {
    let image: NSImage

    var body: some View {
        Image(nsImage: image)
            .resizable()
            .scaledToFit()
            .padding()
            .onDrag {
                guard let tiffRepresentation = image.tiffRepresentation,
                      let bitmapImage = NSBitmapImageRep(data: tiffRepresentation),
                      let bitmapRepresentation = bitmapImage.representation(using: .png, properties: [:]) else {

                    return NSItemProvider(item: image.tiffRepresentation as NSSecureCoding?, typeIdentifier: kUTTypeTIFF as String)
                }

                let provider = NSItemProvider(item: bitmapRepresentation as NSSecureCoding?,
                                              typeIdentifier: kUTTypePNG as String)

                provider.previewImageHandler = { (handler, _, _) -> Void in
                    handler?(bitmapRepresentation as NSSecureCoding?, nil)
                }

                return provider
            }
    }
}

如果我将图像拖到 TextEdit 或电子邮件应用程序等应用程序上,DraggableImage 结构会按预期工作。见下文:

但是,我无法将图片拖动到任何基于文件的应用程序(如 Finder window)上。见下文:

将相同的东西拖到桌面(技术上是全屏 Finder window):

实施中缺少什么?

PS:完整的演示项目托管在 GitHub 上,供对实施感兴趣的人使用。

您需要导出文件 URL 而不是 Data,因此该文件可以被 MacOS 复制。

基本示例:

let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("dragExport.png")
try! bitmapRepresentation.write(to: url)

let provider = NSItemProvider(item: url as NSSecureCoding?, typeIdentifier: kUTTypeFileURL as String)
provider.suggestedName = url.lastPathComponent