3

I'm trying to use the drag and drop methods to drag an .mp3 file from finder into my app (using mac catalyst). So far I have succeeded in getting (I guess) the raw data from the mp3 file into an array, but I'm not sure how to proceed. What I ultimately want is to play the .mp3 file that is dropped into the app with AVAudioPlayerNodes. Is this the right way, or should I try to get the URL of the file instead and then copy it to my app? Any help would be awesome. Thank you.

Code : Delegate methods

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
      if session.localDragSession == nil {
          print("yes")
          return UIDropProposal(operation: .copy)
      }
        print("no")
      return UIDropProposal(operation: .cancel)
    }

    func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
        print("somethng happened")
        session.loadObjects(ofClass: MP3Class.self) { objects in
            for url in objects as! [MP3Class] {
                print(url)
                print(objects)
            }
        }
    }

    func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
        return session.canLoadObjects(ofClass: MP3Class.self)
    }

    func customEnableDropping(on view: UIView, dropInteractionDelegate: UIDropInteractionDelegate) {
        let dropInteraction = UIDropInteraction(delegate: dropInteractionDelegate)
        view.addInteraction(dropInteraction)
    } 

Custom mp3 class :

class MP3Class: NSObject, NSItemProviderReading {
    let data: Data?

    required init(mp3Data: Data, typeIdentifier: String) {
        data = mp3Data
    }

    static var readableTypeIdentifiersForItemProvider: [String] {
        return [kUTTypeMP3 as String]
    }

    static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self {
        return self.init(mp3Data: data, typeIdentifier: typeIdentifier)
    }
}
Willeke
  • 14,578
  • 4
  • 19
  • 47
patturik
  • 135
  • 1
  • 8

1 Answers1

3

Ok I managed to get it working. So it was pretty simple, just needed to create a directory in the documents folder in the performDrop method and then you can simply write the data to a filepath, so for me it was :

        do {
            try url.data!.write(to: filePath, options: .atomic)
            print("succes")
        } catch {
            print("Failed while storing files.")
        }

In which filePath refers to a .mp3 file. That's it. I thought maybe I couldn't play the mp3 this way, but it works like a charm. The only thing that doesn't work yet is to get the same filename as the original data. But I'm sure there's a trick for that as well :)

patturik
  • 135
  • 1
  • 8
  • Did you ever solve the issue with the filename? I am trying to do something similar, and for the life of me I can not get any details about the original dropped file. – Marc-André Weibezahn Jun 25 '23 at 18:11