Contenido del curso

Operaciones CRUD en un proyecto con MVVM

Función addTodo con Core Data en SwiftUI

Resumen

Construir una app de tareas con MVVM en SwiftUI requiere conectar tres piezas: la vista, el ViewModel y el modelo de Core Data. Aquí aprendes cómo implementar la función addTodo y diseñar la pantalla de creación con bindings, state y un DatePicker configurado por rango.

Cómo se implementa la función addTodo en el ViewModel

La función addTodo vive dentro de TodoViewModel y es la encargada de recibir los datos desde la vista y persistirlos en Core Data. Recibe tres parámetros: un título de tipo string, una nota también de tipo string (opcional en la práctica, aunque se envía siempre) y una fecha que indica cuándo se crea la tarea [02:00].

Dentro de la función creas una instancia de la entidad TodoEntity apuntando al contexto del contenedor de Core Data mediante storeContainer.viewContext. Ese contexto es el puente entre tu ViewModel y el almacenamiento local.

¿Qué es UUID en Core Data? Es una clase que genera un identificador único para cada registro. Lo asignas con newTodo.id = UUID() para evitar que dos tareas compartan el mismo identificador.

Luego asignas las propiedades de la entidad: title, note, date, y dos flags que arrancan en false: isComplete y isArchived. Una nueva tarea nunca nace completada ni archivada [04:30]. Al final, llamas a saveData(), función creada en clases anteriores, que persiste los cambios en el contenedor.

Cómo se conecta la vista TodoAddView con el ViewModel

La vista de creación se llama TodoAddView y necesita acceder al ViewModel para invocar addTodo. Para lograrlo, declaras una variable con la notación @Environment, que inyecta un conjunto de datos compartidos entre vistas.

Esta vista no ocupa la pantalla completa. Se presenta como una hoja flotante usando el componente TodoSheet definido en las vistas comunes. Para controlar su visibilidad, agregas una variable showed de tipo boolean con la notación @Binding, que permite modificar su valor desde el lugar que invoca la hoja.

Por qué usar @State para título, nota y fecha

Dentro de TodoAddView declaras tres variables privadas con la notación @State. Esto mantiene su valor seguro frente a cualquier cambio durante la ejecución y refresca la vista cuando el usuario escribe o selecciona algo:

  • title: arranca como cadena vacía.
  • note: arranca como cadena vacía.
  • date: arranca con Date(), la fecha y hora actual.

¿Para qué sirve @State en SwiftUI? Marca una propiedad como fuente de verdad local. Cuando su valor cambia, SwiftUI vuelve a renderizar la vista automáticamente.

Cómo se diseñan los campos de entrada con TodoTextInput y DatePicker

Dentro del VStack agregas los elementos visuales que el usuario manipula. El primero es un TodoTextInput, componente personalizado que combina un label superior y una caja de texto. Recibe tres parámetros: el placeholder ("Ingrese nombre tarea"), el binding del texto ($title) y el label visible ("Tarea") [11:40].

El segundo TodoTextInput repite la estructura, ahora con placeholder "Escriba una descripción de la tarea", binding $note y label "Nota". Este campo es opcional para el usuario.

El tercer elemento es un DatePicker nativo de SwiftUI. Le pasas dos parámetros: selection: $date para guardar la fecha elegida e in: datesRange para limitar el rango de selección. Lo acompañas con un texto "Fecha y hora" en font(.title3), color primario de la app y un padding vertical de ocho o nueve unidades.

Cómo definir un rango de fechas con ClosedRange

Para que el calendario no muestre un abanico infinito, declaras una variable privada datesRange de tipo ClosedRange<Date>. Dentro tomas Calendar.current, defines startDate con Date.now y calculas endDate con:

swift private var datesRange: ClosedRange<Date> { let calendar = Calendar.current let startDate = Date.now let endDate = calendar.date(byAdding: .year, value: 10, to: startDate) ?? startDate return startDate...endDate }

Con esto, el usuario solo puede elegir fechas desde hoy y hasta diez años en el futuro [17:20]. El operador ... construye el ClosedRange que el DatePicker necesita.

Cómo verificar la vista previa antes de conectar el botón Guardar

Para revisar el resultado en el canvas, descomenta el bloque #Preview y, temporalmente, comenta la línea de @Environment o pásale un valor como .constant(true) al binding showed. Esto evita errores mientras la vista no recibe el ViewModel desde su contenedor real.

En la vista previa verás el campo de tarea, el campo de nota opcional, el DatePicker con etiqueta "Fecha y hora" y el botón Guardar en la parte inferior. Todo dentro del TodoSheet, que se comporta como hoja flotante sobre la pantalla principal.

La funcionalidad del botón Guardar, que disparará addTodo con los tres parámetros, queda lista para conectarse en la siguiente sesión. ¿Cómo organizarías tú la validación del título antes de guardar? Cuéntalo en los comentarios.