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.
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.
- Definir un modelo persistente con
@Model. - Configurar el
ModelContainerde 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
}
}
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().
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).
- Crea un modelo
Notacon@Model(título y contenido). - Añade
.modelContainer(for: Nota.self)a tu app. - En una vista, lee
@Environment(\.modelContext). - Crea un formulario que inserte una
Notaconcontext.insert(...). - Cierra y reabre la app: comprueba que el dato sigue ahí (en la próxima lección lo mostrarás con
@Query).