🔄 Antes de iOS 16, implementar drag-and-drop o compartir datos personalizados requería trabajar con NSItemProvider, serialización manual y mucho código repetitivo. Todo eso cambió con Transferable.
✨ El protocolo Transferable del framework Core Transferable permite describir de forma declarativa cómo tus tipos personalizados se serializan y deserializan para transferencias de datos. Lo mejor: funciona automáticamente con APIs de SwiftUI como ShareLink, PasteButton, draggable() y dropDestination().
🎯 Para adoptar Transferable solo necesitas definir una propiedad estática: transferRepresentation. Esta representación le dice al sistema cómo convertir tu tipo en datos transferibles y cómo reconstruirlo después. Apple proporciona tres formas principales de representación según tus necesidades.
📦 CodableRepresentation: la opción más directa cuando tu tipo ya conforma Codable. El sistema serializa automáticamente a JSON y maneja toda la conversión por ti. Ideal para estructuras de datos estándar de tu app.
import UniformTypeIdentifiers
extension UTType {
static var nota: UTType = UTType(exportedAs: "com.miapp.nota")
}
struct Nota: Codable, Transferable {
var id: UUID
var titulo: String
var contenido: String
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .nota)
}
}
💾 DataRepresentation: perfecta cuando necesitas control total sobre la conversión binaria. Defines manualmente cómo exportar tu tipo a Data y cómo importarlo de vuelta. Útil cuando trabajas con formatos personalizados en memoria.
struct Publicacion: Codable, Transferable {
var texto: String
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(contentType: .plainText) { publicacion in
// Exportar: Publicacion → Data
publicacion.texto.data(using: .utf8) ?? Data()
} importing: { data in
// Importar: Data → Publicacion
let contenido = String(decoding: data, as: UTF8.self)
return Publicacion(texto: contenido)
}
}
}
📁 FileRepresentation: diseñada para contenido respaldado por archivos en disco como PDFs, videos o imágenes grandes. Evita cargar todo en memoria pasando URLs de archivo directamente. Esencial para contenido multimedia pesado.
🔗 Para otro tipo de representaciones, ProxyRepresentation añade flexibilidad. Por ejemplo, un objeto complejo puede compartirse como JSON pero copiarse como texto simple en un campo de texto. Múltiples representaciones para contextos diferentes.
extension Publicacion: Transferable {
static var transferRepresentation: some TransferRepresentation {
CodableRepresentation(contentType: .publicacion)
ProxyRepresentation(exporting: \.titulo)
}
}
⚡ Usar estos tipos en SwiftUI es sorprendentemente simple. Con los modificadores draggable() y dropDestination() implementas funcionalidad completa de arrastrar y soltar en pocas líneas. El sistema gestiona toda la complejidad por ti.
struct VistaLista: View {
@State private var elementos: [Nota] = []
var body: some View {
List(elementos) { nota in
Text(nota.titulo)
.draggable(nota)
}
.dropDestination(for: Nota.self) { items, location in
elementos.append(contentsOf: items)
return true
}
}
}
🎨 El framework Uniform Type Identifiers describe los tipos de archivo para almacenamiento o transferencia. Para tipos personalizados debes declarar tu propio UTType en la configuración del proyecto. Esto garantiza que el sistema reconozca tus formatos propietarios.
🚀 Tipos comunes como String, Data, URL, Image y AttributedString ya conforman Transferable. Puedes usarlos inmediatamente sin configuración adicional en operaciones de arrastrar, soltar y compartir. El sistema maneja todo automáticamente. Sin tener que picar ninguna línea adicional de código, cuando arrastras o compartes algo Transferable, el sistema lo serializa y lo copia en memoria. Al soltar o pegar, lo deserializa y reconstruye la instancia original. Todo transparente para el desarrollador.
👨💻 Dominar Transferable es esencial para crear experiencias modernas de compartir y colaborar en tus apps SwiftUI. ¿Ya lo estás usando en tus proyectos?


Deja un comentario