DropDelegate Safari 拖动图像

DropDelegate Safari drag image

我正在尝试实现 DropDelegate 模式以允许将图像拖到我的视图中并加载它们。这适用于来自 finder 的图像,但是当将图像从 safari 拖到我的视图中时,这不起作用。

我注意到所提供的 info/provider 的 typeIdentifierUTType 不可用。有人可以帮我从 safari 拖放这张图片吗?

struct DropImageView: View, DropDelegate {
    @State private var image = NSImage(systemSymbolName: "crop", accessibilityDescription: nil)

    func performDrop(info: DropInfo) -> Bool {
        print("Performing drop: \(info)")
        if info.hasItemsConforming(to: [.image]), let provider = info.itemProviders(for: [.image]).first {
            print(info.itemProviders(for: [String]()))
            print("Image, provider: \(provider)")
            provider.loadItem(forTypeIdentifier: "", options: nil) { something, error in
                print(something ?? error!)
            }
        } else if info.hasItemsConforming(to: [.fileURL]), let provider = info.itemProviders(for: [.fileURL]).first {
            print("FileURL, provider: \(provider)")
            provider.loadDataRepresentation(forTypeIdentifier: UTType.fileURL.identifier) { data, error in
                if let data = data, let path = String(data: data, encoding: .utf8), let url = URL(string: path) {
                    print(data, path, url)
                    DispatchQueue.main.async {
                        self.image = NSImage(contentsOf: url)
                    }
                }
            }
        } else {
            print("Unsupported, info: \(info)")
            return false
        }
        return true
    }

    var body: some View {
        VStack {
            if let image = image {
                Image(nsImage: image)
            }
            Text("Please drop your image here...")
        }
        .onDrop(of: [.image, .fileURL], delegate: self)
    }
}

通过拖动我的 SO 个人资料图片立即输出示例

Performing drop: DropInfo(platformDropInfo: SwiftUI.(unknown context at fff42656708).DropInfo_Mac(location: (111.75277709960938, 28.4794921875), pasteboard: <NSPasteboard: 0x60000198e760>))
[<NSItemProvider: 0x600001681ff0> {types = (
)}]
Image, provider: <NSItemProvider: 0x600001681d50> {types = (
)}
Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load representation of type " UserInfo={NSLocalizedDescription=Cannot load representation of type }

该问题与缺少的类型标识符有关。通过支持 UTType.image,我确实设法让有效的拖放工作。

func performDrop(info: DropInfo) -> Bool {
    print("Performing drop: \(info)")
    if info.hasItemsConforming(to: [.image, .jpeg, .tiff, .gif, .png, .icns, .bmp, .ico, .rawImage, .svg]) {
        let providers = info.itemProviders(for: [.image, .jpeg, .tiff, .gif, .png, .icns, .bmp, .ico, .rawImage, .svg])

        let types: [UTType] = [.image, .png, .jpeg, .tiff, .gif, .icns, .ico, .rawImage, .bmp, .svg]

        for type in types {
            for provider in providers {
                if provider.registeredTypeIdentifiers.contains(type.identifier) {
                    print("Provider \(provider) found for \(type.identifier)")
                    provider.loadDataRepresentation(forTypeIdentifier: type.identifier) { data, error in
                        if let data = data {
                            DispatchQueue.main.async {
                                self.image = NSImage(data: data)
                            }
                        }
                        print(data ?? error!)
                    }
                    return true
                }
            }
        }
    }
    return false
}