Issue #594

In some case, we should not use base type like UTType.text but to be more specific like UTType.utf8PlainText

import UniformTypeIdentifiers

var dropTypes: [UTType] {
    [
        .fileURL,
        .url,
        .utf8PlainText,
        .text
    ]
}

func handleDrop(info: DropInfo) -> Bool {
    for provider in info.itemProviders(for: dropTypes) {
        for type in dropTypes {
            provider.loadDataRepresentation(forTypeIdentifier: type.identifier) { data, _ in
                guard
                    let data = data,
                    let string = String(data: data, encoding: .utf8)
                else { return }

                DispatchQueue.main.async {
                    let item =Item(text: string)
                    withAnimation {
                        self.stack.items.append(item)
                    }
                }
            }
        }


        return true
    }

    return true
}

Handle image drop

func handleDrop(_ info: DropInfo) -> Bool {
    if let provider = info.itemProviders(for: [.fileURL]).first {
        provider.loadDataRepresentation(
            forTypeIdentifier: UTType.fileURL.identifier,
            completionHandler: { data, error in
                if let data = data,
                   let string = String(data: data, encoding: .utf8),
                   let url = URL(string: string),
                   url.isImageFile,
                    let image = NSImage(contentsOf: url) {
                    DispatchQueue.main.async {
                        self.image = image
                    }
                }
            }
        )
        
        return true
    }
    
    return false
}

struct SelectFileView: View {
    @State var isDrop: Bool = false

    var body: some View {
        VStack(alignment: .leading) {
            ...
        }
        .border(isDrop ? R.color.separator : Color.clear)
        .onDrop(of: [.fileURL], delegate: self)
    }
}

extension SelectFileView: DropDelegate {
    func dropEntered(info: DropInfo) {
        self.isDrop = true
    }

    func dropExited(info: DropInfo) {
        self.isDrop = false
    }

    func performDrop(info: DropInfo) -> Bool {
        handleDrop(info)
    }
}


Read more