SwiftUI Audio File Export via draggable

Hey everyone,

TL;DR How do I enable a draggable TableView to drop Audio Files into Apple Music / Rekordbox / Finder?

Intro / skip me I've been dabbling into Swift / SwiftUI for a few weeks now, after roughly a decade of web development.

So far I've been able to piece together many things, but this time I'm stuck for hours with no success using Forums / ChatGPT / Perplexity / Trial and Error.

The struggle

  • Sometimes the target doesn't accept the dropping at all
  • sometimes the file data is failed to be read
  • when the drop succeeds, then only as a stream in apple music

My lack of understanding / where exactly I'm stuck I think the right way is to use UTType.fileUrl but this is not accepted by other applications. I don't understand low-level aspects well enough to do things right.

The code I'm just going to dump everything here, it includes failed / commented out attempts and might give you an Idea of what I'm trying to achieve.

//
//  Tracks.swift
//  Tuna Family
//
//  Created by Jan Wirth on 12/12/24.
//
import SwiftySandboxFileAccess
import Files
import SwiftUI
import TunaApi

struct LegacyTracks: View {
    @State var tracks: TunaApi.LoadTracksQuery.Data?
    func fetchData() {
        print("fetching data")
        
        Network.shared.apollo.fetch(query: TunaApi.LoadTracksQuery()) { result in
            switch result {
            case .success(let graphQLResult):
                self.tracks = graphQLResult.data
            case .failure(let error):
                print("Failure! Error: \(error)")
            }
        }
        
    }
    
    @State private var selection = Set<String>()
    
    var body: some View {
        Text("Tracks").onAppear{
            fetchData()
        }
        
        if let tracks = tracks?.track {
            
            Table(of: LoadTracksQuery.Data.Track.self, selection: $selection) {
                
                TableColumn("Title", value: \.title)
            } rows : {
                ForEach(tracks) { track in
                    TableRow(track)
                        .draggable(track)
//                        .draggable((try? File(path: track.dropped_source?.path ?? "").url) ?? test_audio.url) // This causes a compile-time error
//                        .draggable(test_audio.url)
//                        .draggable(DraggableTrack(url: test_audio.url))
//                            .itemProvider {
//                                let provider = NSItemProvider()
//                                if let path = self.dropped_source?.path {
//                                    if let f =  try? File(path: path) {
//                                        print("Transferring", f.url)
//
//                        
//                                    }
//                                }
//                                
//                                provider.register(track)
//                                return provider
//                            } // This does not
                }
                
            }


            .contextMenu(forSelectionType: String.self) { items in
                // ...
                
                Button("yoooo") {}
            } primaryAction: { items in
                print(items)
                // This is executed when the row is double clicked
            }
        } else {
            Text("Loading")
        }
        
        //        }
        
    }
    
}
//extension Files.File: Transferable {
//    public static var transferRepresentation: some TransferRepresentation {
//        FileRepresentation(exportedContentType: .audio) { url in
//            SentTransferredFile( self.)
//        }
//    }
//}

struct DraggableTrack: Transferable {
    var url: URL
    public static var transferRepresentation: some TransferRepresentation {
        FileRepresentation (exportedContentType: .fileURL) { item in
            SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true)
        }
        
//        FileRepresentation(contentType: .init(filenameExtension: "m4a")) {
//            print("file", $0)
//            print("Transferring fallback", test_audio.url)
//            return SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true)
//        }
//        importing: { received in
//            //            let copy = try Self.(source: received.file)
//            return Self.init(url: received.file)
//        }
//        ProxyRepresentation(exporting: \.url.absoluteString)
    }
}


extension LoadTracksQuery.Data.Track: @retroactive Identifiable {
    
}
import UniformTypeIdentifiers
extension LoadTracksQuery.Data.Track: @retroactive Transferable {
//    static func getKind() -> UTType {
//        var kind: UTType = UTType.item
//        if let path = self.dropped_source?.path {
//            if let f =  try? File(path: path) {
//                print("Transferring", f.url)
//                if (f.extension == "m4a") {
//                    kind = UTType.mpeg4Audio
//                }
//                if (f.extension == "mp3") {
//                    kind = UTType.mp3
//                }
//                if (f.extension == "flac") {
//                    kind = UTType.flac
//                }
//                if (f.extension == "wav") {
//                    kind = UTType.wav
//                }
//
//            }
//        }
//        return kind
//    }
    
    public static var transferRepresentation: some TransferRepresentation {
        ProxyRepresentation {
            $0.dropped_source?.path ?? ""
        }
        FileRepresentation(exportedContentType: .fileURL) { <#Transferable#> in
            SentTransferredFile(<#T##file: URL##URL#>, allowAccessingOriginalFile: <#T##Bool#>)
        }
        
//        FileRepresentation(contentType: .fileURL) {
//            print("file", $0)
//            if let path = $0.dropped_source?.path {
//                if let f =  try? File(path: path) {
//                    print("Transferring", f.url)
//                    return SentTransferredFile(f.url, allowAccessingOriginalFile: true)
//                }
//            }
//            print("Transferring fallback", test_audio.url)
//            return SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true)
//        }
//        importing: { received in
//            //            let copy = try Self.(source: received.file)
//            return Self.init(_fieldData: received.file)
//        }
//        ProxyRepresentation(exporting: \.title)
    }
}
SwiftUI Audio File Export via draggable
 
 
Q