Contents

Transferable

A protocol that describes how a type interacts with transport APIs such as drag and drop or copy and paste.

Declaration

@preconcurrency protocol Transferable : Sendable

Overview

To conform to the Transferable protocol, implement the transferRepresentation property. For example, an image editing app’s layer type might conform to Transferable to let people drag and drop image layers to reorder them within a document.

struct ImageDocumentLayer {
    init(data: Data) { }
    func data() -> Data { Data() }
    func pngData() -> Data { Data() }
}

The following shows how you can extend ImageDocumentLayer to conform to Transferable:

extension ImageDocumentLayer: Transferable {
    static var transferRepresentation: some TransferRepresentation {
        DataRepresentation(contentType: .layer) { layer in
            layer.data()
        } importing: { data in
            ImageDocumentLayer(data: data)
        }
        DataRepresentation(exportedContentType: .png) { layer in
            layer.pngData()
        }
    }
}

When people drag and drop a layer within the app or onto another app that recognizes the custom layer content type, the app uses the first representation. When people drag and drop the layer onto a different image editor, it’s likely that the editor recognizes the PNG file type. The second transfer representation adds support for PNG files.

The following declares the custom layer uniform type identifier:

extension UTType {
    static let layer = UTType(exportedAs: "com.example.layer")
}

If one of your existing types conforms to Codable, Transferable automatically handles conversion to and from Data. The following declares a simple Note structure that’s Codable and an extension to make it Transferable:

struct Note: Codable {
    let title: String
    let body: String
}

extension Note: Transferable {
    static var transferRepresentation: some TransferRepresentation {
        CodableRepresentation(contentType: .note)
    }
}

To ensure compatibility with other apps that don’t know about the custom note type identifier, the following adds an additional transfer representation that converts the note to text.

extension Note: Transferable {
    static var transferRepresentation: some TransferRepresentation {
        CodableRepresentation(contentType: .note)
        ProxyRepresentation(\.title)
    }
}

The order of the representations in the transfer representation matters; place the representation that most accurately represents your type first, followed by a sequence of more compatible but less preferable representations.

Topics

Implementing a transfer representation

Initializers

Instance Properties

Instance Methods

Type Methods

See Also

Essentials