Programación en Swift y SwiftUI para iOS Developers

SwiftData vs Core Data : Qué framework deberías elegir?

Introducción: El Dilema de Guardar Datos

Si llevas tiempo desarrollando para el ecosistema de Apple, conoces el miedo. Ese momento en el que tu aplicación pasa de ser una simple interfaz bonita a necesitar guardar información compleja de forma permanente. Durante más de una década, la respuesta por defecto (y casi obligatoria) fue Core Data.

Core Data es una bestia. Es potente, madura y capaz de manejar grafos de objetos con millones de nodos sin despeinarse. Pero también es famosa por su curva de aprendizaje vertical, su “boilerplate” (código repetitivo) excesivo y su tendencia a castigar severamente al desarrollador que olvida en qué hilo de ejecución se encuentra.

Con la llegada de SwiftUI, la comunidad empezó a sentir una fricción. SwiftUI es declarativo, ligero y moderno. Core Data, con sus raíces en Objective-C, se sentía como intentar instalar un motor de vapor en un Tesla. Funcionaba, pero no encajaba.

En la WWDC 2023, Apple respondió a nuestras plegarias con SwiftData. No es solo una capa de pintura sobre Core Data; es un rediseño filosófico de cómo gestionamos la persistencia, construido por y para Swift.

En este artículo, desglosaremos qué son exactamente ambas tecnologías, sus diferencias fundamentales y, lo más importante, cómo se comparan cara a cara en un proyecto real de Xcode.


Parte 1: El Veterano – ¿Qué es Core Data?

Para entender el futuro, debemos respetar el pasado. Core Data no es una base de datos. Repítelo conmigo: Core Data no es una base de datos. Es un marco de trabajo para la gestión de grafos de objetos y su ciclo de vida.

Por debajo, suele usar SQLite para guardar los datos en disco, pero su trabajo real es gestionar las relaciones entre tus objetos (Entidades), asegurar que los datos sean válidos, y manejar la memoria de tu dispositivo cargando solo lo que necesitas (Faulting).

Los componentes del miedo

Core Data requiere entender una arquitectura compleja:

  1. Managed Object Model: El esquema visual (.xcdatamodeld).
  2. Persistent Store Coordinator: El intermediario entre el modelo y el disco.
  3. Managed Object Context (MOC): El “pizarrón” donde realizas cambios antes de guardar.
  4. NSPersistentContainer: La caja que intenta agrupar todo lo anterior para facilitarte la vida.

En SwiftUI, integrar esto implicaba inyectar el contexto en el entorno (@Environment(\.managedObjectContext)) y usar el property wrapper @FetchRequest. Aunque funcional, siempre se sintió un poco “ajeno” a la sintaxis limpia de Swift.


Parte 2: El Retador – ¿Qué es SwiftData?

SwiftData es la persistencia reimaginada para la era de la concurrencia y las macros de Swift. Si Core Data es manual y explícito, SwiftData es automático e implícito.

Su filosofía se basa en “Code-First” (El código primero). Ya no necesitas dibujar diagramas en un editor visual. Tus propias clases de Swift son tu esquema de base de datos. Utiliza el nuevo sistema de Macros de Swift (introducido en iOS 17) para transformar clases normales en modelos persistentes sin que tengas que escribir código de “pegamento”.

¿Reemplaza a Core Data?

Técnicamente, SwiftData es Core Data bajo el capó. Usa la misma infraestructura de almacenamiento probada durante años, pero elimina toda la complejidad de la API antigua. Es como si Apple hubiera automatizado las mejores prácticas de Core Data y las hubiera escondido detrás de una API elegante.


Parte 3: Las 5 Diferencias Capitales

Aquí es donde entraremos en el detalle técnico. ¿Qué cambia realmente en tu día a día en Xcode?

1. Definición del Modelo: Editor Visual vs. Macros

Core Data: Tradicionalmente, creas un archivo .xcdatamodeld. Abres un editor gráfico, añades una “Entidad”, defines atributos (String, Integer) y configuras relaciones manualmente. Luego, Xcode genera (o tú escribes) una subclase de NSManagedObject.

  • Problema: El archivo de modelo y el código pueden desincronizarse. Los tipos de datos son limitados y antiguos.

SwiftData: Simplemente escribes una clase y le pones @Model.

// SwiftData
@Model
class Tarea {
    var titulo: String
    var fecha: Date
    var completada: Bool
    
    // Relaciones automáticas
    var categoria: Categoria?

    init(titulo: String, fecha: Date = Date()) {
        self.titulo = titulo
        self.fecha = fecha
        self.completada = false
    }
}
  • Ventaja: Es código Swift puro. Puedes usar Enums, Structs (si son Codable) y lógica calculada directamente en tu modelo.

2. Configuración del Stack (Boilerplate)

Core Data: Necesitas un PersistenceController (generalmente unas 50-80 líneas de código) que configure el NSPersistentContainer, maneje la carga de tiendas persistentes y gestione los errores fatales.

SwiftData: La configuración se reduce a un modificador en tu vista principal de SwiftUI:

@main
struct MiApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: Tarea.self) // ¡Solo una línea!
    }
}

SwiftData infiere todo el esquema y configura la base de datos automáticamente basándose en la clase Tarea.

3. Consultas de Datos: FetchRequest vs. @Query

Core Data (@FetchRequest): Requiere NSSortDescriptor (una API antigua de Objective-C) y a menudo NSPredicate basado en cadenas de texto, lo cual es propenso a errores tipográficos que no se detectan hasta que la app se cierra inesperadamente (crash).

@FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Tarea.fecha, ascending: true)],
    animation: .default)
private var tareas: FetchedResults<Tarea>

SwiftData (@Query): Totalmente “Type-Safe” (seguro en tipos). Usas sintaxis nativa de Swift.

@Query(sort: \.fecha, order: .forward) 
var tareas: [Tarea]

Además, SwiftData introduce el macro #Predicate. Esto permite escribir filtros complejos verificados por el compilador. Si te equivocas en el nombre de una variable, Xcode te avisa antes de compilar.

4. Guardado Automático y Hilos (Threading)

En Core Data, tú eres responsable de guardar el contexto (context.save()). Si olvidas hacerlo, los datos se pierden. Si intentas acceder a un objeto de la base de datos desde un hilo secundario sin usar performBlock, la app crashea.

SwiftData introduce el concepto de Autosave (activado por defecto). El sistema detecta cambios en tus modelos (gracias a la observación de SwiftUI) y los persiste periódicamente o cuando la app pasa a segundo plano. Además, SwiftData utiliza el sistema de actores (Actors) de Swift para manejar la concurrencia de forma mucho más segura.

5. Migraciones

Cuando cambias tu modelo (ej. añades un campo “prioridad” a la Tarea), la base de datos debe actualizarse.

  • Core Data: Requiere crear versiones del modelo, mapeo ligero o pesado, y puede ser un dolor de cabeza.
  • SwiftData: Maneja las migraciones ligeras automáticamente. Simplemente añades la variable a tu clase, le das un valor por defecto, y SwiftData actualiza el esquema SQL la próxima vez que lanzas la app.

Parte 4: Tutorial Práctico – Creando una App de Notas

Vamos a ver cómo se ve el código real comparando ambos enfoques para una operación simple: Guardar una nueva nota.

Enfoque Core Data

Primero, necesitas obtener el contexto del entorno:

struct NuevaNotaView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @State private var texto = ""

    var body: some View {
        Button("Guardar") {
            let nuevaNota = Nota(context: viewContext)
            nuevaNota.texto = texto
            nuevaNota.fecha = Date()

            do {
                try viewContext.save()
            } catch {
                // Manejar error manualmente
                print("Error al guardar: \(error)")
            }
        }
    }
}

Nota la verbosidad: tienes que instanciar pasándole el contexto y manejar el try-catch explícitamente.

Enfoque SwiftData

Necesitas el modelContext, que es la evolución del managedObjectContext.

struct NuevaNotaView: View {
    @Environment(\.modelContext) private var context
    @State private var texto = ""

    var body: some View {
        Button("Guardar") {
            let nuevaNota = Nota(texto: texto) // Inicializador Swift normal
            context.insert(nuevaNota)
            // ¡No hace falta llamar a save() explícitamente!
        }
    }
}

Es más limpio. Tratas el objeto como una clase normal de Swift y simplemente le dices al contexto: “Oye, inserta esto”.


Parte 5: ¿Cuándo NO usar SwiftData?

A pesar de las maravillas de SwiftData, no es la solución perfecta para todos, al menos no todavía en 2025.

  1. Compatibilidad iOS: SwiftData requiere iOS 17 como mínimo. Si tu empresa necesita dar soporte a iOS 15 o 16, estás atado a Core Data.
  2. Complejidad Extrema: Si tu app tiene un grafo de datos masivo con reglas de migración muy personalizadas, o si compartes la base de datos con extensiones escritas en Objective-C, Core Data sigue siendo más robusto.
  3. CloudKit Público: Al momento de escribir esto, SwiftData se integra maravillosamente con iCloud privado (sincronizar los datos del usuario entre sus dispositivos), pero la integración con bases de datos públicas de CloudKit aún está más madura en Core Data.

Conclusión

La transición de Core Data a SwiftData es similar a la transición de Objective-C a Swift. Al principio, puedes echar de menos el control granular y explícito del “viejo estilo”, pero rápidamente te das cuenta de que la productividad y la seguridad que ganas valen la pena.

SwiftData elimina la barrera de entrada a la persistencia en iOS. Convierte una tarea que solía tomar días de configuración y aprendizaje en algo que puedes implementar en una tarde.

¿Mi recomendación?

  • Si empiezas un proyecto nuevo hoy (Greenfield) y puedes permitirte apuntar a iOS 17+: Usa SwiftData sin dudarlo.
  • Si tienes un proyecto existente en Core Data: No lo reescribas todavía. Ambas tecnologías pueden coexistir (puedes tener entidades de Core Data y modelos de SwiftData en la misma app), pero la migración completa requiere planificación.

El futuro es declarativo, seguro y rápido. SwiftData es, sin duda, el motor de ese futuro.

Si tienes cualquier duda sobre este artículo, contacta conmigo y estaré encantado de ayudarte 🙂. Puedes contactar conmigo en mi perfil de X o en mi perfil de Instagram

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Cómo añadir compras integradas en una aplicación en SwiftUI

Next Article

Conferencias iOS y Swift en 2026

Related Posts