macosswiftuidrag-and-dropmac-catalystnsitemprovider

Getting file URL from NSItemProvider on macCatalyst always fails


I have a SwiftUI/Catalyst app that shall receive audio/video files per drag/drop.

On a certain view I have the fowling modifier, which accepts the specified media files.

      .onDrop(of: ["public.movie","public.audio"], isTargeted: nil, perform: { providers in
        print(providers.first)
        
        let _ = providers.first?.loadObject(ofClass: URL.self, completionHandler: { (url, _) in
          print(url)
        })
        return true
      })

When I drop a file, the returned provider prints

Optional(<NSItemProvider: 0x600002ae4b60> {types = ( "com.apple.m4a-audio", "com.apple.finder.node" )})

which looks OK. However when I try to determine the URL of the dropped file I always get nil.

What is wrong with this code ?


Solution

  • The item provider doesn't provide the public.file-url type identifier, so I would not expect you to be able to load a URL from it. In other words, your app is simply not provided with a URL.

    If you want a URL, you can load it as a file using loadFileRepresentation, which would save a temporary copy of the data as a file.

    providers.first?.loadFileRepresentation(for: .data, completionHandler: { url, error in
        if let url {
            print(url) // file:///var/folders/_6/3vl5c2c14fvb9kwttb_f2vxm0000gn/T/.com.apple.Foundation.NSItemProvider.tInGux/foo.mp3
    
            // copy the file to somewhere else...
        }
    })