Ejercicio parte II. recuperar los datos
Info
Esta sección es un ejercicio a seguir paso a paso que vale 0,5 puntos de la nota del bloque de iOS
Vamos a añadir una pantalla donde se puedan consultar las notas que tenemos almacenadas. Las listaremos en una table view y por el momento se verán todas, no se podrán filtrar (añadiremos esa posibilidad cuando veamos la sintaxis de las "consultas" o fetch requests).
Para recuperar todas las instancias de una entidad como un array debemos crear y ejecutar una fetch request sin "predicado" (sin condiciones, como si fuera un SELECT
sin WHERE
), por ejemplo para listar todas las Nota
s haríamos algo como:
//IMPORTANTE: estamos poniendo los tipos de request y results para que se vea cuáles son
//pero el compilador no nos obligará a ponerlos
let request : NSFetchRequest<Nota> = Nota.fetchRequest()
//la línea anterior la podríamos poner también como
//let request = NSFetchRequest(entityName:"Nota")
//es probable que lo veáis así en muchos libros/ejemplos de código
//ejecutamos la query
//suponiendo que "miContexto" sea el contexto de persistencia
let results : [Nota] = try! miContexto.fetch(request)
Vamos a hacer esto en nuestra app, aunque necesitaremos enlazar este código con la parte de UI.
La interfaz de usuario¶
Sigue estos pasos:
- Crear el Tab Bar Controller: teniendo seleccionada la única pantalla de la aplicación, ve al menú y selecciona
Editor > Embed In > Tab Bar Controller
. Se creará el tab bar controller, por el momento con una única "solapa" que será la pantalla de creación de notas - En la pantalla de creación de notas, pulsa sobre el item de la barra inferior para editarlo, y ponle como
Title
por ejemploNueva
, para que se vea que es la pantalla de creación de notas - Crear la pantalla para listar notas: Arrastrar al storyboard un
Table view controller
. Recuerda que es una especie de tabla a “pantalla completa”. - Vincular la nueva pantalla al tab bar controller: hacer
Ctrl+Arrastrar
desde la pantalla del tab bar hasta la de listado de notas. En el menú contextual elegir como tipo del segue el de,View Controllers
(bajoRelationship Segue
).- Cambia el título del item de la barra inferior para que ponga "Lista" o algo similar.
- Vamos a configurar la interfaz de la nueva pantalla
- Cambia el aspecto del prototipo de la tabla: pulsa sobre la celda prototipo de la tabla, y en las propiedades cambia el
Style
a `Basic - Pon un reuse identifier: pon algún
Identifier
por ejemploMiCelda
(recuerda que este identificador se emplea luego en el código para solicitar al sistema instancias reutilizables de celdas)
- Cambia el aspecto del prototipo de la tabla: pulsa sobre la celda prototipo de la tabla, y en las propiedades cambia el
- Ahora vamos a configurar el controlador de la pantalla
- Primero tenemos que crear un controlador (
File>New>File...
). De las plantillas que aparecen usaCocoa Touch Class
, así Xcode generará código por nosotros. La clase se debe llamarListaNotasController
y heredará deUITableViewController
.
- Primero tenemos que crear un controlador (
- Ahora hacer que la nueva clase sea el controlador de la pantalla de listado de notas:
- en el storyboard tienes que seleccionar la pantalla de listado de notas (primero de los iconos de la barra superior, el de fondo amarillo)
- En el Identity Inspector (cuarto de los iconos del panel de la derecha de Xcode, ), como
Class poner
ListaNotasController`
Pon un print("hola soy ListaNotasController")
en el viewDidLoad
del ListaNotasController
para comprobar que efectivamente se usa esta clase como controlador de la nueva pantalla.
Prueba a ejecutar el proyecto para ver que funciona el cambio de pantallas en el tab bar controller y que efectivamente en la pantalla de lista aparece el print
hecho por ListaNotasController
.
El código de la pantalla de listado¶
En la tabla vamos a mostrar un array de notas. Lo primero será definir una propiedad para almacenarlas en la clase ListaNotasController
//RECUERDA que hace falta este import al principio del archivo
import CoreData
class ListaNotasController: UITableViewController {
var listaNotas : [Nota]!
}
Solo nos queda rellenar el array de notas. En ListaNotasController
crea un método
override func viewWillAppear(_ animated: Bool) {
}
Vamos a rellenarlo de código. Para recuperar datos de Core Data se usa un fetch request, que sería algo así como una consulta. para crearlo, inicializamos una instancia pasándole el nombre de la entidad resultado de la consulta. Para ejecutarlo, llamamos al método fetch
del contexto. Veamos un ejemplo. Escribe el siguiente código en el viewWillAppear
(Recuerda que debes sacar de algún lado el contexto de Core Data (miContexto
)). Este código todavía no mostrará las notas en la tabla pero al menos sí por la consola.
let request = Nota.fetchRequest()
//ACLARACION: "miContexto" es el contexto de Core Data
//FALTA el código que obtiene "miContexto", como se ha hecho en ejemplos anteriores
//Ejecutamos la "query"
let notas = try! miContexto.fetch(request)
for nota in notas {
print(nota.texto!)
}
Nótese que los fetch request usan tipos. Es decir, devuelven un conjunto de elementos de una clase determinada, en nuestro caso Nota
.
Si pruebas el proyecto, al navegar a la pantalla de lista, los textos de las notas deberían aparecer en la consola de Xcode (aunque no en la pantalla del simulador).
Para que los datos de las notas aparezcan en la tabla, debes:
- Asignar el valor devuelto por
miContexto.fetch
a la propiedadself.listaNotas
, que has creado antes - Forzar el refresco de la tabla para que aparezcan los datos. Tras asignar el valor a listaNotas, haz
self.tableView.reloadData()
(En unUITableViewController
la propiedadtableView
referencia a la tabla, no hace falta crear el outlet) - Modificar los métodos que ha creado Xcode:
numberOfSections
debe devolver 1 en vez de 0, ya que la tabla tiene 1 seccióntableView(_ tableView: UITableView, numberOfRowsInSection section: Int)
debe devolver el tamaño del arraylistaNotas
(propiedadcount
)- El siguiente método, que está comentado, debes descomentarlo, y hacer un par de modificaciones:
- Donde hace el
dequeReusableCell...
, cambia el identificador de la celda por el que hayas elegido tú antes al crear esta pantalla (aquí se sugeríaMiCelda
) - Donde pone el comentario
Configure the cell...
hacer que como texto de la celda aparezca el texto de la nota correspondiente
cell.textLabel?.text = self.listaNotas[indexPath.row].texto as? String