Suppose we have a SwiftData Model:
@Model
class Contact {
var firstName: String?
var lastName: String?
}
We make this model Codable (I’ll skip showing the implementation; it’s standard). Now we want to allow our user to drag and drop instances of this model object around. Maybe from a List row to a group in a sidebar, or out of our app and into another app like Mail or Notes.
We declare a custom UTType and want to export as JSON. So we attempt to do this:
extension Contact: Transferable
{
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(for: Contact.self, contentType: .ourCustomUTType)
}
}
In Swift 6 language mode, the compiler throws a fit:
Conformance of 'Contact' to 'Sendable' is unavailable: PersistentModels are not Sendable, consider utilizing a ModelActor or use Contact's persistentModelID instead
It seems strange that Transferable implies Sendable, because we’re not sending the actual thing; we’re sending a representation of it. A JSON blob, some Data, a String, etc. (I guess maybe the encoding happens on any thread in the pool.)
What’s the elegant way of dealing with this in Swift 6? I don’t want to transfer just the persistentModelID. It’s pointless to transfer that when the user drags to Mail, Notes, etc. I want to construct a JSON file and transfer that.
Thus far, all I can think to do is create a “wrapper” struct:
struct ContactShim: Transferable
{
let jsonData: Data
init(_ contact: Contact) {
// convert contact to JSON data.
}
static var transferRepresentation: some TransferRepresentation {
// provide jsonData instead of Codable.
}
}
Surely there’s a better way?