Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the filename of dropped file in SwiftUI?

I have been trying to find out how to get the filename of an image dropped into a SwiftUI View.

The code fragment is as follows:

struct MainView: View, DropDelegate {

  @ObservedObject var userState : UserState

  var body : some View {
    Group {
      if (self.userState.editing) {
        BlackoutView()
      } else {
        DropView()
      }
    }
    .frame(minWidth: 320, idealWidth: 640, maxWidth: .infinity, minHeight: 240, idealHeight: 480, maxHeight: .infinity, alignment: .center)
    .onDrop(of: [(kUTTypeImage as String), "public.pdf"], delegate: self)
  }

  func dropUpdated(info: DropInfo) -> DropProposal? {
    let proposal = DropProposal.init(operation: .copy)
    return proposal
  }

  func performDrop(info: DropInfo) -> Bool {
    print("perform drop")
    userState.editing = true
    return true
  }

}

When I drop an image onto the app, it runs performDrop. How can one obtain the filename of the image dropped onto the app?

It runs on macOS.

like image 231
teusbenschop Avatar asked Oct 27 '19 14:10

teusbenschop


1 Answers

Having spent more than an hour struggling with the apis (the documentation is almost nonexistent), here is what worked for me:

// The onDrop registration
.onDrop(of: [(kUTTypeFileURL as String)], delegate: self)

...

func performDrop(info: DropInfo) -> Bool {

    guard let itemProvider = info.itemProviders(for: [(kUTTypeFileURL as String)]).first else { return false }

    itemProvider.loadItem(forTypeIdentifier: (kUTTypeFileURL as String), options: nil) {item, error in
        guard let data = item as? Data, let url = URL(dataRepresentation: data, relativeTo: nil) else { return }
        // Do something with the file url
        // remember to dispatch on main in case of a @State change
    }

    return true
}

Please note that I have omitted any validation, so this code grabs the first url from any dropped files

like image 123
Alladinian Avatar answered Oct 14 '22 23:10

Alladinian