Ejercicio de SQLite: app de tareas pendientes
En este ejercicio vamos a crear una pequeña aplicación de gestión de tareas pendientes, en la que se puedan listar tareas y añadir tareas nuevas. Cada tarea tiene un id (entero, autonumérico), un titulo (cadena), una prioridad (entero) y un vencimiento (fecha). Las columnas están por este orden en la tabla.
Configurar el proyecto
- Crear un proyecto llamado
TareasSQLitede tipo Master-Detail Application - En la carpeta
archivos SQLitede las plantillas hay unos cuantos recursos que debes copiar al proyecto- Copia en el proyecto la base de datos
tareas.db. Usa el menúFile > Add files to TareasSQLite...y selecciona el archivotareas.db. En el cuadro de diálogo de copia, pulsa sobre el botonoptionsde la parte inferior y asegúrate de que la casilla deCopy files if neededestá marcada. - Copia en el proyecto el
DBManager.swift, es muy parecido al que tienes en los apuntes.
- Copia en el proyecto la base de datos
Ahora hay que configurar el proyecto para poder usar SQLite
- Añade la librería
libsqlite3.tbdsegún se explica en los apuntes. - Crea el
bridging-header.hsegún se explica en los apuntes
Para comprobar que funciona, introduce el siguiente código en el método viewDidLoad del MasterViewController
let manager = DBManager(conDB:"tareas",reload:false)
Si todo es correcto, en el log debe aparecer el mensaje “BD abierta”. Una vez que sepas que funciona puedes quitar esta línea para que no interfiera con el resto del ejercicio.
Nótese que como primer parámetro se pasa el nombre de la BD (sin la extensión .db), y como segundo un booleano indicando si la copia de la BD de Documents se va a sobreescribir cada vez que se arranque la aplicación (útil cuando en desarrollo estamos cambiando “desde fuera” la BD para hacer pruebas)
Si por algún motivo cambias manualmente la estructura o el contenido de la base de datos, recuerda poner el parámetro
reloadatruela primera vez que ejecutes la aplicación tras la modificación
Infraestructura básica (0,1 puntos)
- Crea una
structSwift llamadaTareay añádele como propiedades:idde tipoInttitulode tipoStringprioridadde tipoIntvencimientode tipoDate
- Crea una clase llamada
TareasManagerque sea una subclase deDBManager. En los siguientes apartados implementaremos aquí las operaciones con la tabla de tareas.
Funcionalidad 1: Listar tareas (0,6 puntos)
Implementar el listado en sí
En TareasManager Implementa un método listarTareas que debe devolver un array de objetos Tarea ordenados por fecha de vencimiento. Será muy similar al código que sirve para listar personas en los apuntes.
Ten en cuenta que las fechas de
tareas.dbestán almacenadas al estilo “tiempo UNIX”: número de segundos transcurridos desde el 1/1/1970
Mostrar las tareas en la interfaz
Para probar que el código funciona vamos a introducir código en el MasterViewController
Añade la siguiente propiedad para almacenar una referencia al TareasManager
let tm : TareasManager!
En el viewDidLoad coloca el siguiente código, para probar el listado de tareas. Fijate que la propiedad objects ya está definida en la plantilla de Xcode, y que es un NSMutableArray de objetos a mostrar en pantalla (nosotros haremos que sean tareas)
self.tm = TareasManager(conDB: "tareas", reload: false)
self.objects = self.tm.listarTareas()
for (tarea in self.objects) {
print("\(t.titulo)");
}
Verás que además aparecen las tareas en el interfaz gráfico (ya que la plantilla de Xcode automáticamente rellena la tabla con los datos del array objects), AUNQUE no aparecen bien, se ve su dirección de memoria. Vamos a arreglar esto.
Mostrar las tareas en la tabla
Para que las tareas aparezcan correctamente el interfaz gráfico puedes cambiar la línea en el método tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) que dice
cell.textLabel!.text = object.description
por otra que ponga en la etiqueta de texto la propiedad titulo de la tarea
let tarea = object as Tarea
cell.textLabel!.text = tarea.titulo
Para poder ver algún detalle más en la lista, por ejemplo la fecha de vencimiento, abrir el storyboard y seleccionar la celda de tabla que aparece en la segunda pantalla de la aplicación. En las propiedades, cambiar el Style de Basic a Subtitle, por ejemplo (aunque también valdrían los otros dos estilos).
En el código de tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) incluir código que
- convierta
objecta Tarea - acceda a su propiedad
vencimiento(que será un UNIX timestamp) - Convierta este timestamp a una fecha en formato texto (mira los apuntes)
- Asigne esta fecha en formato texto a `cell.detailTextLabel.text
Funcionalidad 2: Insertar nueva tarea (0,3 puntos)
Implementar la “lógica” para esta funcionalidad
Implementar un método func insertarTarea(tarea : Tarea)->Bool en la clase TareasManager, que inserte una nueva tarea en la BD y devuelva true si todo ha ido bien y false en caso contrario.
Al campo
idno es necesario darle valor al insertar un registro ya que es autonumérico.
Para comprobar que funciona correctamente, en el viewDidLoad del MasterViewController. puedes colocar código que cree una tarea (hazlo antes del que las lista, para que la nueva esté incluida también en la lista de tareas)
let nueva = Tarea()
nueva.titulo = @"Tarea nueva";
nueva.prioridad = 1;
//24*60*60 segundos posterior a la fecha actual -> mañana a la misma hora
nueva.vencimiento = Date(timeIntervalSinceNow:24*60*60);
self.tm.insertarTarea(nueva)
Incorporar la funcionalidad de nueva tarea al interfaz sería interesante pero excesivo, ya que el objetivo del ejercicio es el trabajo con SQLite, no con la GUI de iOS.