I was also looking for a workaround, but I think I actually came up with a workable solution. I took a completely different approach by not trying to drag and drop the PersistentModel objects themselves, but instead, dragging and dropping the PersistentIdentifier struct from a PersistentModel object. This works well because PersistentIdentifier is already Codable and it is very easy to make it Transferable. Also, a PersistentIdentifier struct can be used to retrieve its corresponding PersistentModel object from the ModelContext.
I have published a complete working sample program demonstrating this on GitHub: https://github.com/Whiffer/SwiftDataDragAndDropExample
The important concepts are:
Extend PersistentIdentifier to be Transferable and define your own contentType for it
extension PersistentIdentifier: Transferable {
public static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .persistentModelID)
}
}
Extend PersistentIdentifier with a generic convenience function to retrieve PersistentModel objects from the ModelContext
extension PersistentIdentifier {
public func persistentModel<Model>(from context: ModelContext) -> Model? where Model : PersistentModel {
return context.model(for: self) as? Model
}
}
Use PersistentIdentifier structs with the .draggable() and .dropDestination() View Modifiers
Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
.draggable(item.persistentModelID)
.dropDestination(for: PersistentIdentifier.self) { persistentModelIDs, _ in
let targetItem = item // for clarification
for persistentModelID in persistentModelIDs {
if let draggedItem: Item = persistentModelID.persistentModel(from: self.modelContext) {
print("\(draggedItem.timestamp) dropped on: \(targetItem.timestamp)")
}
}
return true
}