wandres.dev
SWIFTDATA · persistencia moderna

SwiftData: @Model y persistencia

Guarda datos en disco con SwiftData: define modelos con la macro @Model, configura el contenedor y guarda con el ModelContext. Persistencia sin ceremonia.

⏱ 15 min

Las apps recuerdan cosas: tus tareas, tus notas, tus ajustes. SwiftData es la respuesta moderna de Apple a la persistencia — defines modelos con una macro, y guardar y cargar de disco pasa casi solo. Sin archivos .xcdatamodeld ni NSManagedObject.

🎯 Al terminar esta lección sabrás
  • Definir un modelo persistente con @Model.
  • Configurar el ModelContainer de la app.
  • Insertar, borrar y guardar con el ModelContext.
  • Entender cómo encaja con SwiftUI.

El modelo: @Model

Marca una clase con @Model y SwiftData la convierte en persistente. Cualquier propiedad se guarda automáticamente:

import SwiftData

@Model
class Tarea {
    var titulo: String
    var completada: Bool
    var creada: Date

    init(titulo: String, completada: Bool = false) {
        self.titulo = titulo
        self.completada = completada
        self.creada = .now
    }
}
ℹ️
Sí, es una clase

Aunque en el Nivel 1 aprendiste a preferir structs, los modelos de SwiftData son clases (@Model solo funciona en clases). Tiene sentido: un registro persistente tiene identidad —es la misma fila de la base de datos aunque la edites desde varias vistas—, y la identidad es justo lo que caracteriza a los tipos de referencia. Es la excepción que confirma la regla.

El contenedor: dónde viven los datos

La app necesita un ModelContainer que gestione el almacén. Se configura en el punto de entrada con una línea:

@main
struct MiApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: Tarea.self)   // crea y comparte el almacén
    }
}

Esto crea la base de datos (SQLite por debajo), la conecta y la inyecta en el environment para todas las vistas. Una línea y ya tienes persistencia.

Guardar y borrar: el ModelContext

El ModelContext es tu ventana a los datos: insertas, borras y él persiste. Lo lees del environment:

struct AñadirTarea: View {
    @Environment(\.modelContext) private var context
    @State private var titulo = ""

    var body: some View {
        Form {
            TextField("Título", text: $titulo)
            Button("Guardar") {
                let tarea = Tarea(titulo: titulo)
                context.insert(tarea)        // se guarda automáticamente
            }
        }
    }
}

Para borrar: context.delete(tarea). SwiftData guarda los cambios por ti en la mayoría de los casos; si necesitas forzarlo, try? context.save().

Editar es aún más simple: no hay que guardar

El detalle que sorprende: como los modelos @Model son observables, editar una propiedad ya persiste el cambio. Si tienes una tarea y haces tarea.completada = true, SwiftData detecta la modificación y la guarda sola. No hay un paso explícito de “actualizar en la base de datos”. Cambias el objeto en memoria y el disco se sincroniza. Esa integración entre el modelo, la observación y la persistencia es lo que hace a SwiftData tan directo comparado con lo anterior.

El flujo completo

📐

1. Modela

Clase con @Model por cada tipo que guardes.

📦

2. Contén

.modelContainer(for:) en la app.

✍️

3. Escribe

context.insert / delete, o edita el objeto.

🔎

4. Lee

@Query en las vistas (próxima lección).

⚔️ Tu primer dato persistente
  1. Crea un modelo Nota con @Model (título y contenido).
  2. Añade .modelContainer(for: Nota.self) a tu app.
  3. En una vista, lee @Environment(\.modelContext).
  4. Crea un formulario que inserte una Nota con context.insert(...).
  5. Cierra y reabre la app: comprueba que el dato sigue ahí (en la próxima lección lo mostrarás con @Query).