Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación,...

50
Proyecto de Integración Índice 1 Caso de estudio e interfaz iOS..................................................................................... 2 1.1 Requerimientos generales........................................................................................ 2 1.2 Servicios REST........................................................................................................ 2 1.3 Aplicación iOS......................................................................................................... 5 1.4 Ejercicios................................................................................................................17 2 Interfaz Android......................................................................................................... 24 2.1 Aplicación Android................................................................................................ 24 2.2 Ejercicios................................................................................................................29 3 Persistencia Android................................................................................................... 32 3.1 Introducción........................................................................................................... 32 3.2 Ejercicios................................................................................................................32 4 Persistencia iOS.......................................................................................................... 38 4.1 Introducción........................................................................................................... 38 4.2 Ejercicios................................................................................................................38 5 Servicios Web iOS..................................................................................................... 46 5.1 Introducción........................................................................................................... 46 5.2 Ejercicios................................................................................................................46 Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Transcript of Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación,...

Page 1: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Proyecto de Integración

Índice

1 Caso de estudio e interfaz iOS..................................................................................... 2

1.1 Requerimientos generales........................................................................................ 2

1.2 Servicios REST........................................................................................................2

1.3 Aplicación iOS.........................................................................................................5

1.4 Ejercicios................................................................................................................17

2 Interfaz Android......................................................................................................... 24

2.1 Aplicación Android................................................................................................24

2.2 Ejercicios................................................................................................................29

3 Persistencia Android...................................................................................................32

3.1 Introducción........................................................................................................... 32

3.2 Ejercicios................................................................................................................32

4 Persistencia iOS..........................................................................................................38

4.1 Introducción........................................................................................................... 38

4.2 Ejercicios................................................................................................................38

5 Servicios Web iOS..................................................................................................... 46

5.1 Introducción........................................................................................................... 46

5.2 Ejercicios................................................................................................................46

Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 2: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

1. Caso de estudio e interfaz iOS

1.1. Requerimientos generales

El objetivo general del proyecto será la creación de dos aplicaciones (una basada enAndroid y otra basada en iOS) para la gestión de una colección de libros, mediante el usode Servicios Web. La aplicación de Android nos permitirá gestionar los datos relativos alos libros, permitiendo añadir o eliminar libros de la base de datos general, editar susdatos o buscarlos, por poner unos cuantos ejemplos. La aplicación de iOS será la que nospermitirá gestionar nuestra colección de libros propiamente dicha a partir de los librosexistentes en el sistema.

1.2. Servicios REST

Nuestro proyecto se construirá sobre una serie de servicios web RESTful que nos daránacceso a una biblioteca online. A continuación detallaremos las funcionalidades que nosproporcionan estos servicios.

Al sistema podrán acceder cuatro tipos de usuarios: bibliotecarios, profesores, alumnos yusuarios no registrados. Los bibliotecarios podrán gestionar la colección de libros de labiblioteca (altas, modificaciones, borrados). Los alumnos y profesores podrán reservarlibros, siempre que estén disponibles en la sala, para ir a recogerlos. Por último, cualquierusuario, aunque no esté registrado en el sistema, podrá consultar la colección de librosque tenemos en la biblioteca.

Proyecto de Integración

2Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 3: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Casos de uso de los servicios REST

Las operaciones que puede realizar cualquier usuario son las siguientes:

• Obtener el listado con todos los libroshttp://server.jtech.ua.es:8080/jbib-rest/resources/libros

• Obtener un listado de libros paginadohttp://server.jtech.ua.es:8080/jbib-rest/resources/libros?firstResult=2&maxResults=4

• Buscar libros por título y autorhttp://server.jtech.ua.es:8080/jbib-rest/resources/libros?keyword=Pattern

• Obtener los datos de un libro dado su isbnhttp://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572

• Obtener la imagen de la portada de un librohttp://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572/imagen

Proyecto de Integración

3Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 4: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Casos de uso públicos

Los usuarios bibliotecarios podrán gestionar la colección de libros:

• Añadir nuevos libros a la colecciónhttp://server.jtech.ua.es:8080/jbib-rest/resources/libros (POST)

• Eliminar libros de la bibliotecahttp://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572(DELETE)

• Modificar los datos de un librohttp://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572 (PUT)

• Subir una nueva imagen de portada para un librohttp://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572/imagen(PUT)

Proyecto de Integración

4Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 5: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Casos de uso de los bibliotecarios

Por último, los usuarios profesores o alumnos podrán reservar un libro, siempre que estédisponible para reserva:

http://server.jtech.ua.es:8080/jbib-rest/resources/libros/0131401572/reserva(POST)

Todas las operaciones permiten intercambiar la información en formato XML(application/xml) o JSON (application/json), excepto aquellas que trabajan conimágenes, que utilizan formato JPEG (image/jpeg).

1.3. Aplicación iOS

Vamos a comenzar con el proyecto de aplicación para la plataforma iOS. En este casovamos a implementar una aplicación que permita manejar nuestra colección de libros,permitiéndonos compartir con nuestros contactos de Twitter y Facebook informaciónsobre la misma. Nuestra colección de libros se almacenará de forma local en nuestrodispositivo. Podremos añadir nuevos libros a la colección local a partir del catálogoofrecido por los servicios web anteriores.

De los libros de la biblioteca obtendremos los datos proporcionados por los servicios web(isbn, título, autor, fecha de alta, número de páginas e imagen de la portada). Cuandoguardemos un libro en nuestra colección, además de los datos anteriores añadiremos elestado actual del libro y su puntuación. El estado actual nos indicará si no hemos leído ellibro todavía, lo estamos leyendo actualmente, o ya lo hemos leído. En la puntuaciónpodremos darle una valoración de 0 a 10 a los libros de nuestra colección.

Proyecto de Integración

5Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 6: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Para almacenar los libros utilizaremos el siguiente objeto de dominio:

typedef enum {UAEstadoLibroSinLeer,UAEstadoLibroLeyendo,UAEstadoLibroLeido,

} UAEstadoLibro;

@interface UALibro : NSObject

@property(nonatomic,strong) NSString *isbn;@property(nonatomic,strong) NSString *titulo;@property(nonatomic,strong) NSString *autor;@property(nonatomic,strong) NSDate *fecha;@property(nonatomic,assign) NSUInteger paginas;@property(nonatomic,strong) UIImage *imagen;@property(nonatomic,assign) NSInteger puntuacion;@property(nonatomic,assign) UAEstadoLibro estado;

@end

Parte de la funcionalidad de la aplicación requerirá el acceso a datos remotos mediante losservicios web anteriores (añadir nuevos libros a nuestra colección, a partir del catálogo dela biblioteca), mientras que otros datos serán almacenados de manera local (gestión denuestra colección). Cuando se lleven a cabo las siguientes acciones será necesario accedera datos remotos:

• Obtener el listado completo de libros de la biblioteca, lo que nos permitirá añadirnuevos libros a nuestra colección.

• Visualizar los datos de un libro de la biblioteca.• Buscar un libro de la biblioteca por título o ISBN.• Compartir datos mediante Facebook y Twitter.

El resto de funcionalidades de la aplicación serán:

• Añadir un libro a nuestra colección particular.• Consultar la lista de libros de nuestra colección.• Eliminar un libro de nuestra colección.• Puntuar libros de nuestra colección.• Cambiar el estado de un libro (leído, leyendo, sin leer).

Las operaciones remotas necesitarán acceder a las URLs de los servicios webespecificados anterioremente y obtener la información de los libros, mientras que lasoperaciones locales accederán a los datos mediante Core Data. El acceso a datos remotosy locales se implementará en próximas sesiones de proyecto. Por el momento vamos aimplementar únicamente la interfaz de la aplicación. Para poder dar funcionalidad a dichainterfaz, se proporciona un singleton llamado UAFuenteDatos que nos proporcionarátodas las operaciones anteriores, pero sobre colecciones de libros en memoria, en lugar deutilizar persistencia y acceso a servicios web. Las operaciones ofrecidas por este singletonson las siguientes:

• Acceso a la colección de libros de la biblioteca (propiedad librosBiblioteca).Corresponde a los libros a los que accederemos a través del servicio web.

Proyecto de Integración

6Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 7: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

• Acceso a nuestra colección local de libros (propiedad librosColeccion).Corresponde a los libros que almacenaremos mediante Core Data.

• Cadenas de texto que utilizaremos en la aplicación para cada estado de los libros(propiedad cadenaEstadoLibro). Los estados son: sin leer, leyendo, leído.

• Búsqueda de libros de la biblioteca filtrando por título (métodobuscaLibrosPorTitulo:).

• Búsqueda de libros de la biblioteca filtrando por ISBN (métodobuscaLibrosPorIsbn:).

• Comprobación de si ya tenemos añadido un determinado libro a nuestra colecciónlocal (método existeLibroEnColeccionConIsbn:).

• Obtención del porcentaje de libros leídos (método porcentajeLibrosLeidos).• Obtención de la valoración media de los libros de nuestra colección (método

notaMediaLibrosColeccion).• Obtención de un libro de nuestra colección de forma aleatoria (método

libroAleatorio).

La interfaz principal de la aplicación estará basada en pestañas. Podemos encontrar lassiguientes pestañas:

• Inicio: Pantalla con el logo del curso, donde aparecerá destacado un libro de nuestracolección seleccionado de forma aleatoria.

• Colección: Nos permite ver el listado de libros de nuestra colección, sus datos, ymodificar su estado y su valoración. También podremos eliminar libros de lacolección desde el listado.

• Agregar: Nos permite obtener el listado de libros de la biblioteca y hacer búsquedasen él. Cuando estemos viendo un libro de la biblioteca podremos añadirlo a nuestracolección local.

• Estadísticas: Nos muestra estadísticas sobre nuestra colección de libros (número delibros, libros leídos, puntuación media).

• Configuración: Nos permite configurar la dirección a la que deberá conectar paraacceder al repositorio central de libros.

A continuación detallamos el funcionamiento de las diferentes vistas que se deberánimplementar en la aplicación.

1.3.1. Vista principal

Se mostrará un logo de la aplicación y la portada de alguno de los libros presentes ennuestra colección, en el caso en el que ésta contenga alguno. Provisionalmente, dado queno estamos guardando la colección de forma persistente, seleccionaremos aleatoriamenteun libro del conjunto de libros de la biblioteca.

Proyecto de Integración

7Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 8: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de inicio

1.3.2. Vista de la colección

Muestra un listado con todos los libros en nuestra colección. Para cada libro se mostrarásu portada, título y autor (utilizaremos el tipo de celda con subtítulo). En la barra denavegación tendremos un botón de edición, y entrando en modo de edición podremosborrar libros de la colección. También podremos realizar el borrado realizando un gestode "barrido" sobre las celdas. Seleccionando cualquiera de las celdas será posiblevisualizar los datos del libro.

Proyecto de Integración

8Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 9: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de nuestra colección

1.3.3. Vista de datos del libro

Al seleccionar un libro de la colección, veremos una pantalla con los datos del libro.Tendremos una tabla agrupada con dos secciones. En la sección superior tendremos unaúnica celda con la imagen del libro, su título, su autor, y su número de páginas. En lasección inferior veremos una celda con el estado del libro y otra con su puntuación. Lapuntuación se cambia mediante un control de tipo stepper. Al pulsar sobre dicho controlla etiqueta con el valor numérico de la valoración se actualizará.

Proyecto de Integración

9Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 10: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de datos del libro

Pulsando sobre la celda con el estado nos mostrará una lista con los posibles estados dellibro, apilando la pantalla en el controlador de navegación. Desde dicha lista podremoscambiar el estado, y al volver atrás veremos el nuevo estado en los datos del libro.

Proyecto de Integración

10Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 11: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de cambio de estado del libro

1.3.4. Vista de búsqueda de libros de la biblioteca

Esta vista, correspondiente a la pestaña Agregar, nos permitirá acceder al listadocompleto de libros de la biblioteca, o realizar búsquedas por título o isbn dentro de estacolección. Para ello tendremos una barra de búsqueda, con un selector de ámbito que nospermitirá elegir entre "Título" e "Isbn". Si no introducimos texto en la barra de búsquedanos aparecerá la colección de libros completa.

Proyecto de Integración

11Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 12: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de libros de la biblioteca

Si introducimos texto en la barra de búsqueda, filtrará el listado según el título o isbnintroducido.

Proyecto de Integración

12Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 13: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de búsqueda en los libros de la biblioteca

Para cada libro en el listado se mostrará su portada, su autor y su título. Al pusar sobrecualquiera de los libros se accederá a la vista que permitirá visualizar los datos del mismoy agregarlo a nuestra colección.

1.3.5. Vista para agregar un nuevo libro

Aparecerá al seleccionar uno de los libros de la biblioteca. En ella veremos los datos dellibro seleccionado. Mostrará su portada, isbn, título, autor, fecha de alta, y número depáginas. En la barra de navegación contendrá un botón que permitirá añadir el libro anuestra colección.

Proyecto de Integración

13Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 14: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla para agregar un nuevo libro

Al pulsar el botón para agregar el libro deberá aparecer una alerta para pedirnosconfirmación.

Proyecto de Integración

14Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 15: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Confirmación para agregar un nuevo libro

Una vez agregado, el botón debe aparecer desactivado, y en lugar de "Agregar" tendrácomo texto "En colección", para indicarnos que ya tenemos agregado dicho libro a lacolección.

1.3.6. Vista de estadísticas

Mostrará una tabla agrupada con los siguientes datos:

• Número total de libros de la colección.• Porcentaje de libros que hemos terminado de leer.• Puntuación media de los libros de la colección

Proyecto de Integración

15Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 16: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de estadísticas

1.3.7. Vista de configuración

Mostrará una tabla agrupada en la que podremos configurar la URL que nos da acceso alos servicios de la biblioteca. Por ahora no tendrá ningún efecto cambiar esta información.El cuadro de texto deberá estar integrado en la celda de la tabla.

Proyecto de Integración

16Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 17: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de configuración

1.4. Ejercicios

Vamos a implementar la interfaz de la aplicación utilizando para ello storyboards. Estohará que nuestra aplicación sea compatible únicamente con iOS 5 y versiones superiores,por lo que podremos utilizar sin problemas las nuevas características aparecidas en estaversión de la plataforma.

Se proporciona como plantilla un proyecto con la aplicación parcialmente implementada,en la que falta por añadir las pantallas para consultar y modificar nuestra colección delibros.

Proyecto de Integración

17Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 18: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

El mapa de navegación que implementa la aplicación es el siguiente:

Mapa de navegación

Las pantallas dentro del recuadro rojo son las que deberemos implementar en lospróximos ejercicios.

1.4.1. Subir el proyecto a SVN

Lo primero que haremos es subir el proyecto a SVN. Para ello conectaremos a nuestrorepositorio desde la ventana del Organizer:

• Esquema: svn+ssh• Host: server.jtech.ua.es• Ruta: /home/svn/<mi_login>/• Location: svn+ssh://server.jtech.ua.es/home/svn/<mi_login>/

Dentro del repositorio crearemos un directorio proy-ios, y dentro los subdirectoriostrunk, tags, y branches. Configuraremos estas rutas de forma correcta en laconfiguración del reposotorio en Organizer.

Una vez hecho esto, subiremos a trunk mediante Import el proyecto completo(seleccionar el directorio raíz de BibliotecaJTech, aquel que contiene el fichero.xcodeproj).

Proyecto de Integración

18Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 19: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Tras esto, borraremos el proyecto de disco y haremos un checkout del proyecto de SVN,para así obtener una working copy. Abriremos esta copia de trabajo en el entorno ytrabajaremos con ella a partir de ahora.

1.4.2. Listado de libros de la colección

En primer lugar, vamos a llenar de datos la lista de libros de nuestra colección. Lapantalla ya está creada en el storyboard, pero como controlador de tipo tabla genérico.Deberemos:

1. Cambiar el tipo de controlador en el inspector de identidad. Se proporciona ya uncontrolador parcialmente implementado para esta tarea, cuyo nombre esUAColeccionViewController.

2. Llenar de datos la tabla de libros. Deberemos mostrar la lista de libros de la propiedadlibros del controlador. Introduce para ello el código necesario entableView:numberOfRowsInSection: y tableView:cellForRowAtIndexPath:.En este último deberemos mostrar el título del libro en la etiqueta principal, su autorcomo subtítulo, y la imagen de la portada.

1.4.3. Datos de un libro

Vamos ahora a crear una nueva pantalla con los datos de un libro, de forma que alseleccionar un libro de la tabla nos lleve a esta pantalla. Deberemos:

1. Crear una nueva pantalla en el storyboard. Para ello arrastraremos sobre el editor uncontrolador de tipo tabla (Table View Controller). Haremos que la tabla sea estática(atributo Content a Static Cells) y agrupada (atributo Style a Grouped).

2. Conectaremos la celda de la tabla del controlador de la lista con nuestro nuevocontrolador para los datos de un libro mediante un segue de tipo push, para así apilarla pantalla en el controlador de navegación. Podemos ahora probar en la aplicaciónque la transición se produce correctamente, aunque la pantalla de datos del libro estévacía.

3. Se proporciona un controlador parcialmente implementado para la pantalla de datosde libro en la clase UADatosLibroViewController. Asociaremos la pantalla queacabamos de crear a dicha clase mediante el inspector de identidad.

4. En el controlador UAColeccionViewController introduciremos enprepareForSegue:sender: el código necesario para pasarle al controladorUADatosLibroViewController los datos del libro seleccionado. Podemos utilizar uncódigo como el siguiente:UADatosLibroViewController *datosController =

segue.destinationViewController;datosController.libro = [self.libros

objectAtIndex: self.tableView.indexPathForSelectedRow.row];

5. Crea la interfaz de la pantalla de datos del libro mediante una tabla estática enInterface Builder. Debe quedar tal como se especificó en el apartado correspondientea esta pantalla:

Proyecto de Integración

19Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 20: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Pantalla de datos del libro• Tendrá dos secciones: la primera de ellas con una única celda de altura 165 px, y

la segunda con dos celdas de altura estándar.• En la primera celda tendremos una imagen con la portada del libro, y tres

etiquetas: título, autor y número de páginas.• La segunda sección tendrá como título Información del libro.• La primera celda de la segunda sección será de estilo Right Detail, y como

etiqueta izquierda tendrá el texto Estado. La etiqueta derecha se rellenará encódigo. El Accessory debe ser de tipo Disclosure Indicator.

• La segunda celda de la segunda sección debe ser de tipo Custom, pero cuidaremosque la etiqueta izquierda tenga la misma posición, dimensiones y estilo que la dela celda anterior (utiliza para ello el inspector de tamaño), y tendrá como texto

Proyecto de Integración

20Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 21: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper paramodificarla (debe admitir valores de 0 a 10). Ambos elementos deben aparecercentrados verticalmente.

• La tabla no debe permitir hacer scroll (utiliza el inspector de atributos para ajustaresto).

• Ninguna de las celdas anteriores debe cambiar de color al ser seleccionadas(establecer el atributo Selection a None).

6. Ahora deberemos conectar los elementos creados anteriormente con outlets delcontrolador correspondiente (UADatosLibroViewController). Crea y conecta lossiguientes outlets:• Imagen de la portada• Etiqueta con el título• Etiqueta con el autor• Etiqueta con el número de páginas• Etiqueta con el estado del libro• Etiqueta con la puntuación seleccionada• Stepper para modificar la puntuación

7. Inicializa en viewWillAppear: los valores mostrados por los campos a partir de losdatos del libro (propiedad libro).

8. Conecta el stepper mediante una acción de forma que cada vez que modifiquemos suvalor, actualice los datos del libro en memoria (propiedad libro) y el valor mostradopor la etiqueta en la pantalla. Comprueba que esto tiene repercusión en la pantalla deestadísticas.

1.4.4. Selección de estado del libro

La última pantalla que queda por crear es la que nos permitirá cambiar el estado de unlibro. Cuando tenemos un campo para el que queremos que el usuario pueda seleccionarentre una serie limitada de opciones, como es el caso del estado del libro, lo habitual esapilar una nueva pantalla en el controlador de navegación en la que mostraremos una listaen la que se mostrarán las diferentes opciones disponibles y podremos seleccionar una deellas. Al seleccionar una opción ésta aparecerá marcada con una casilla de verificación(Accessory de tipo Checkmark). Para implementar esto deberemos:

1. Crear una nueva pantalla de tipo tabla (Table View Controller) esta vez con celdasdinámicas (atributo Content a Dynamic Prototypes). Crearemos una celda prototipode tipo básico. El identificador de reutilización (atributo Identifier) será CeldaEstado.

2. Establecer la clase de la pantalla como UAEstadoLibroViewController. Estecontrolador ya está completamente implementado. Se encargará de poblar de datos latabla (los cogerá de la lista de posibles estados de los libros), y de gestionar laselección exclusiva de items de la lista (cuando se seleccione un item se marcará conel checkmark y se desmarcará el que estuviese marcado anteriormente, y además semodificarán los datos del libro en memoria).

3. Por último, conectaremos mediante un segue de tipo push la celda de estado de la

Proyecto de Integración

21Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 22: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

pantalla anterior con la nueva pantalla. Con esto la aplicación deberá funcionarcorrectamente.

Pantalla de cambio de estado del libro

1.4.5. Borrado de libros (*)

Vamos a habilitar la posibilidad de borrar libros de nuestra colección desde la pantalla dellistado de libros (UAColeccionViewController). Para ello deberemos:

1. Habilitar el botón de edición tras cargar la vista (viewDidLoad):self.navigationItem.rightBarButtonItem = self.editButtonItem;

2. Implementar el método tableView:commitEditingStyle: para que en caso de

Proyecto de Integración

22Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 23: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

realizarse el borrado se elimine el libro correspondiente de nuestra colección.

Proyecto de Integración

23Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 24: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

2. Interfaz Android

2.1. Aplicación Android

En este apartado explicamos en más detalle los objetivos para la aplicación Android adesarrollar dentro del seno del proyecto de integración. El objetivo será crear unaaplicación que nos permita tratar la base de datos general de libros que luego seráutilizada por los clientes a partir de la aplicación iOS para gestionar sus propiascolecciones. Podremos obtener un listado de los libros almacenados actualmente en labase de datos remota, así como añadir, editar o eliminar libros. Como parte optativa delproyecto se permitirá además visualizar en un mapa de Google la localización de diversaslibrerías de la ciudad de Alicante.

Los libros se obtendrán a partir de los servicios web descritos en la sesión anterior, y sealmacenarán en nuestra aplicación como objetos de la clase Libro:

package es.ua.jtech.proyectointegracion;

import android.graphics.Bitmap;

public class Libro {private String autor;private String isbn;private int numPaginas;private String titulo;private Bitmap portada;

public Libro(String au, String is, int nu, String ti) {autor = au;isbn = is;numPaginas = nu;titulo = ti;portada = null;

}

public String getAutor() { return autor; }public String getIsbn() { return isbn; }public int getNumPaginas() { return numPaginas; }public String getTitulo() { return titulo; }public void setPortada(Bitmap por) { portada = por; }public Bitmap getPortada() { return portada; }

}

Las funcionalidades básicas de la aplicación serán:

• Listado de los libros en la base de datos remota• Visualizar los datos de un libro concreto• Dar de alta o baja un libro• Búsqueda de libros por nombre o ISBN• Editar libros (de manera opcional se podrá modificar la portada del libro a partir de

una fotografía)• Localización de librerías en la ciudad de Alicante mediante un mapa de Google

Proyecto de Integración

24Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 25: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

(optativo)

Varias de las funcionalidades anteriores requerirán el acceso a los servicios webespecificados en la sesión anterior de la documentación del proyecto a través de las URLsespecificadas para obtener la información de los libros. El acceso a los datos remotos, asícomo almacenamiento temporal de datos locales, se llevará a cabo en próximas sesionesdel proyecto. Como primer paso vamos a diseñar la interfaz del proyecto.

Se podrá hacer uso de las funcionalidades anteriores a través de un conjunto deactividades. La navegación entre actividades se llevará a cabo mediante menús. Lasopciones del menú cambiarán según la actividad en la que nos encontremos. Acontinuación detallamos el funcionamiento de las diferentes actividades de la aplicación.

2.1.1. Actividad principal

Se tratará de la actividad principal de la aplicación, a partir de la cual se podrá acceder atodas las funcionalidades de la misma. Su interfaz tan sólo mostrará un logotipo. Desde elmenú de la actividad se podrá realizar cualquiera de las siguientes acciones: obtener unlistado de libros, dar de alta un libro, consultar el mapa de librerías o acceder a lasopciones de configuración. Todas estas opciones lanzarán nuevas actividades (las cualesson explicadas a continuación), excepto la opción de configuración, que permitirámodificar las opciones de login mediante SharedPreferences (esto también estáexplicado más adelante).

Actividad principal

2.1.2. Actividad Listado

Proyecto de Integración

25Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 26: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Permite listar los libros presentes en el sistema. Para cada libro se mostrará una miniaturade la portada, su título y su autor. Al pulsar sobre un libro se mostrará una actividad quepermitirá editar los datos del mismo. El menú de la actividad permitirá además buscar unlibro tanto por título como por ISBN (con lo que aparecerá un cuadro de búsqueda en laparte superior de la actividad) o añadir un libro.

Actividad Listado

2.1.3. Actividad VisualizarLibro

Esta actividad, como su propio nombre indica, permitirá visualizar los datos de un libro.Se mostrará la portada del mismo junto con su título, autor, ISBN y número de páginas.El menú de la actividad permitirá la edición de los datos del libro o su eliminación de labase de datos.

Proyecto de Integración

26Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 27: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Actividad VisualizarLibro

2.1.4. Actividad EditarLibro

Esta actividad se lanzará tanto en el caso de que se desee dar de alta un nuevo libro comoen el caso de haberse seleccionado la opción de editar un libro ya existente. El aspecto deesta actividad será muy similar al de la anterior; la diferencia más importante es que losdatos aparecerán en cuadros de edición, con lo que será posible modificarlos (éstosaparecerán vacíos en el caso de un libro nuevo). El menú de la actividad permitirá guardarlos datos o descartar los cambios (con lo que se volverá a la actividad anterior).Finalmente, al pulsar sobre la portada del libro se nos ofrecerá la opción de tomar unafotografía con nuestro dispositivo móvil para sustituir la portada del libro por la fotografíaque hayamos hecho.

Proyecto de Integración

27Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 28: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Actividad EditarLibro

2.1.5. Actividad MapaLibrerias

Esta actividad simplemente mostrará mediante el control de Google Maps la localizaciónde las librerías más cercanas. Esta localización se obtendrá a partir de un fichero XMLque proporcionaremos los profesores del curso. Al pulsar en cualquiera de los iconos querepresente la localización de una librería se mostrará su nombre mediante un Toast.

Proyecto de Integración

28Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 29: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Actividad MapaLibrerias

2.1.6. Configuración

Finalmente, en cuanto a las opciones de configuración, se hará uso de Shared

Preferences para mostrar una vista que nos permita modificar el nombre de usuario ycontraseña con el que se accederá a las diferentes servicios web que nos permitirán dotarde funcionalidad a nuestra aplicación.

2.2. Ejercicios

El objetivo será la creación de la interfaz para las actividades Listado,VisualizarLibro y EditarLibro con sus correspondientes menús, además deimplementar algunas funcionalidades básicas. De manera temporal utilizaremos una clasesingleton que nos permitirá tener un listado provisional de libros, hasta que nuestraaplicación sea capaz de hacer uso de los servicios web.

Se proporciona como plantilla un proyecto con la aplicación parcialmente implementada,en la que faltan las actividades enumeradas en el párrafo anterior, así como la actividadMapaLibrerias. Entre los recursos de la aplicación se incluyen las imágenes que seutilizarán en el proyecto para los menús.

2.2.1. Subir el proyecto al SVN

Como en el caso del proyecto iOS, lo primero que haremos es subir el proyecto a SVN.Para ello pulsamos con el botón derecho sobre el nombre del proyecto en Eclipse yseleccionamos la opción Share Project.... Los datos del repositorio serán los mismos quese usaron para el proyecto iOS, sólo que en este caso el proyecto tendrá un nombrediferente.

2.2.2. Actividad Listado

La primera actividad que vamos a crear es la actividad Listado, que es la que seencargará de mostrar un listado con los libros. Esta actividad heredará de ListActivity,y se accederá a ella a partir de la opción Listado del menú de la actividad principal.

Llevaremos a cabo los siguientes pasos:

• Creamos la actividad Listado, y hacemos que pueda ser lanzada desde la opcióncorrespondiente del menú de la actividad principal. No olvides añadir el nodoactivity correspondiente al Manifest de la aplicación. En caso contrario se produciráun error en tiempo de ejecución cuando intentes iniciar la actividad.

• Como habrás podido comprobar en la captura de la actividad en secciones anteriores,los elementos del listado tienen un layout propio. Crea un fichero de layoutlibrolistado.xml para cada una de las filas del listado. Recuerda que para cada fila hay

Proyecto de Integración

29Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 30: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

que mostrar una imagen, un título y un autor. Esto se hará mediante un ImageView deidentificador icono y mediante dos vistas TextView con identificadores titulo yautor, respectivamente.

• En las plantillas se te proporciona el código de una clase singleton llamadaSingletonLibros, que utilizaremos de momento para sustituir a los servicios web.Esta clase representa el listado de libros que tendríamos en el servidor. En elconstructor se crean dos libros de ejemplo. Para acceder al listado de libros desde laactividad Listado podemos utilizar el siguiente código, que devuelve un ArrayList

de elementos de la clase Libro:

SingletonLibros.getSingleton().getLibros();

• Para poder asociar cada uno de los libros a las filas del listado, hemos de crear unadaptador propio. En nuestro caso vamos a crear un adaptador como clase privadadentro de Listado que se llamará LibroAdapter. El método más importante de estaclase es getView, que enlaza cada libro del ArrayList con los elementos del layoutlibrolistado.xml. El código de nuestro adaptador será el siguiente:

private class LibroAdapter extends ArrayAdapter<Libro> {

private ArrayList<Libro> items;

public LibroAdapter(Context context, int textViewResourceId,ArrayList<Libro> items) {

super(context, textViewResourceId, items);this.items = items;

}

@Overridepublic View getView(int position, View convertView, ViewGroup parent)

{View v = convertView;

if (v == null) {LayoutInflater vi =

(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);v = vi.inflate(R.layout.librolistado, null);

}Libro l = items.get(position);if (l != null) {

TextView tt = (TextView) v.findViewById(R.id.titulo);TextView bt = (TextView) v.findViewById(R.id.autor);ImageView portada = (ImageView) v.findViewById(R.id.icono);if (tt != null) {

tt.setText(l.getTitulo());}if(bt != null){

bt.setText(l.getAutor());}if (portada != null) {

portada.setImageBitmap(l.getPortada());}

}return v;}

}

• Ahora ya podremos utilizar este adaptador para rellenar el listado de libros.• Crea el menú de la actividad con las opciones indicadas en la especificación. La única

Proyecto de Integración

30Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 31: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

opción que estará activa será la de añadir un nuevo libro, que mostrará la actividadEditarLibro.

• Añade un manejador para que cuando se seleccione un libro del listado se muestre laactividad VisualizarLibro, la cual deberá mostrar los datos del libro seleccionado.

2.2.3. Actividad VisualizarLibro

Esta actividad se mostrará cuando se haya seleccionado algún libro del listado de libros.Su única utilidad es mostrar los datos del libro seleccionado. El primer paso que deberásseguir será crear el layout de la actividad, que deberá tener un aspecto similar al de lacaptura mostrada en las secciones anteriores. Los datos del libro a visualizar se obtendránmediante parámetros extra del Intent que se utilizó para lanzar la actividad.

No olvides crear el correspondiente menú de opciones, que en este caso tendrá tan solodos: una opción para editar el libro que se está visualizando actualmente, y una opciónpara borrar. No olvides tampoco añadir la actividad al Manifest.

2.2.4. Actividad EditarLibro

Esta actividad tendrá una interfaz muy similar a la anterior; la diferencia más importanteserá que los diferentes campos del libro serán elementos del tipo EditText en lugar deTextView. Es posible llegar a esta actividad desde dos lugares. Si se accede desde laopción de añadir un nuevo libro, tanto desde la actividad principal como desde laactividad de listado, todos los campos estarán vacíos. Si se accedió a esta actividad desdela opción de editar un libro, la cual es seleccionable en la actividad de visualizar libros,los campos mostrarán los datos del libro que se pretende editar.

El menú tendrá dos opciones, una para guardar y otra para cancelar. La opción decancelar siempre volverá a la actividad anterior. La opción de guardar tendrá uncomportamiento diferente según la situación: en el caso en el que se trate de un nuevolibro se encargará de añadir un libro a la base de datos. Implementa un método en la claseSingletonLibros para añadir un nuevo objeto Libro al ArrayList con los valoresespecificados en los campos. Para el caso de la edición de libros deberás incorporar unmétodo en la clase SingletonLibros para modificar los datos de un libro determinado.

No olvides tampoco en esta ocasión añadir la actividad al Manifest de la aplicación.

2.2.5. Borrar un libro (*)

Como ejercicio optativo se propone que se implemente la funcionalidad de borrar libros,la cual puede ser accedida mediante la opción correspondiente en la actividadVisualizarLibro.

Proyecto de Integración

31Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 32: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

3. Persistencia Android

3.1. Introducción

En esta segunda sesión del proyecto de integración dedicada a Android trataremos el temade la persistencia de la aplicación. En concreto utilizaremos la persistencia para construiruna caché local de los libros a los cuales se puede acceder a través de los servicios web.Esta caché se construirá mediante una base de datos privada a la aplicación, de tal formaque durante la ejecución de la misma sólo volveremos a hacer uso de los servicios web enel caso en que dicha base de datos se modifique (por ejemplo, tras añadir o eliminar unlibro, o tras editar los datos de alguna entrada de la base de datos).

El objetivo es claro: minimizar al mínimo la latencia producida por el acceso a datosremotos, mejorando la experiencia al usuario y permitiéndole trabajar con la base de datosde libros tal cual si lo estuviera haciendo en remoto.

Puesto que todavía no se ha tratado en el curso el tema de los servicios web, seguiremoshaciendo uso de la clase SingletonLibros para emularlos.

3.2. Ejercicios

El objetivo principal de los ejercicios será la creación de la base de datos privada de laaplicación y su utilización.

3.2.1. Crear el adaptador de la base de datos

El primer paso consistirá en la creación de la clase AdaptadorLibros, que servirá deinterfaz entre la base de datos y el resto de la aplicación. Esta clase hará uso de un Helperpara crear o actualizar la base de datos.

• En primer lugar creamos la clase AdaptadorLibros. Dentro de la misma definimosvalores constantes y estáticos para el nombre de la base de datos (valor bdlibros.dbpara la constante BASE_DATOS), el nombre de la tabla (valor libros para la constanteTABLA) y cada una de las columnas (valores _id, titulo, autor, isbn y paginas en elarray COLUMNAS).

• Añadimos una clase privada LibrosHelper que herede de SQLiteOpenHelper y quetenga la misma estructura que en los apuntes correspondientes a la base de datosSQLite en Android. Definimos una constante privada para AdaptadorLibros quecontenga la sentencia SQL para la creación de la base de datos y que será utilizadadesde LibrosHelper:

private static final String CREAR_BASE_DATOS = "create table " +TABLA + " (" + COLUMNAS[0] +" integer primary key autoincrement, " +

Proyecto de Integración

32Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 33: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

COLUMNAS[1] + " text not null, " +COLUMNAS[2] + " text not null, " +COLUMNAS[3] + " text not null, " +COLUMNAS[4] + " integer not null);";

• No olvides añadir el constructor de AdaptadorLibros, en el que inicializaras unainstancia del Helper, y el método open, en el que inicializarás la instancia privada deSQLiteDatabase del adaptador por medio del método getWritableDatabase delHelper.

3.2.2. Inserción

En este ejercicio llevaremos a cabo los pasos necesarios para preparar nuestro adaptadorpara que pueda llevar a cabo inserciones.

• Para la inserción de datos vamos a utilizar una sentencia compilada (tienes másinformación sobre esto en los ejercicios de la sesión 1 del módulo de persistencia). Enprimer lugar declaramos la siguiente constante en nuestra clase AdaptadorLibros:

private static final String INSERT = "insert into " + TABLA + "(" +COLUMNAS[1] + ","

+ COLUMNAS[2] + "," + COLUMNAS[3] + "," + COLUMNAS[4] + ") values(?,?,?,?)";

• Definimos el atributo privado insertStatement de tipo SQLiteStatement para laclase AdaptadorLibro y lo inicializamos en el método open (tras haber inicializadola instancia a la base de datos; en nuestro ejemplo concreto esta instancia tiene elnombre db) de la siguiente manera:

this.insertStatement = this.db.compileStatement(INSERT);

• Ahora ya podemos utilizar esta sentencia compilada en el método insert deladaptador. Recuerda que primero debes hacer uso de los métodos bindString ybindDouble de insertStatement para a continuación invocar su métodoexecuteInsert.

3.2.3. Método deleteAll

Añadimos a nuestro adaptador el método deleteAll, cuyo cometido será borrar todos loslibros de la base de datos. Para ello utilizamos la siguiente instrucción (donde db es elnombre que se le ha dado a la instancia de la base de datos dentro del adaptador en esteejemplo):

return db.delete(TABLA, null, null)

3.2.4. Probando la inserción

En este ejercicio vamos a comprobar que todo lo que hemos hecho hasta el momento seacorrecto. Para ello, en la actividad Listado, usa la inserción del adaptador para insertaren la base de datos todos los libros obtenidos a partir de la clase SingletonLibros. No

Proyecto de Integración

33Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 34: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

olvides hacer uso del método deleteAll previamente. Para comprobar que los datos sehan insertado correctamente, ejecutamos desde la línea de comandos:

./adb shell

Una vez ejecutando el shell ya podemos ejecutar los siguientes comandos:

#cd /data/data/es.ua.jtech.proyectointegracion/databases#sqlite3 bdlibros.dbsqlite> .schemasqlite> .tablessqlite> select * from libros;

Los libros deberían mostrarse en la tabla libros de la base de datos.

3.2.5. Consultas

Implementa el método query de AdaptadorLibros para que cada vez que se invoquedevuelva un Cursor apuntando a todos los libros almacenados en la base de datos. Paraello debes hacer uso del método query de la instancia de la base de datos en el adaptador.Los únicos parámetros que deberás pasar serán el nombre de la tabla y un array con lascolumnas a obtener (todas menos la clave primaria). El resto de los parámetros a la horade invocar a query tendrán un valor de null.

Puedes comprobar que la consulta funciona correctamente utilizando la clase Log paramostrar en el LogCat los libros almacenados en la base de datos a partir del cursorobtenido por el método query.

3.2.6. Adaptador de ListActivity a partir de un cursor

Una vez que hemos comprobado que las consultas funcionan correctamente, haz lasmodificaciones necesarias en la clase privada LibroAdapter de Listado para que ellistado de libros se construya a partir de los resultados obtenidos del cursor en lugar de losobtenidos a partir de la clase SingletonLibros directamente. En concreto los cambiosque debes hacer son los siguientes:

• La clase LibroAdapter debe ser ahora una subclase de CursorAdapter.• El tipo de items, que era hasta ahora un ArrayList de objetos de tipo Libro, debe

pasar a ser Cursor.• El constructor pasará a tener tan sólo dos parámetros:

public LibroAdapter(Context context, Cursor items) {super(context, items);this.items = items;

}

• Por último debes modificar el método getView. Este método se invoca cada vez quese va a añadir un libro al listado. El índice del libro se indica por el parámetroposition. Para hacer que el cursor apunte al libro correspondiente deberás utilizar:

items.moveToPosition(position);

Proyecto de Integración

34Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 35: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

• Una vez que el cursor apunta al libro correspondiente ya no deberías tener problemaspara asociar los valores de dicho libro a los diferentes campos del layoutlibrolistado.xml que determina el aspecto de cada fila de la lista.

Nota:Eclipse te indicará que faltan algunos métodos por implementar para la clase LibroAdapter.Simplemente añádelos y déjalos vacíos.

Aviso:Al ejecutar tu código es posible que se lance la siguiente excepción:java.lang.IllegalArgumentException: column '_id' does not exist.Para evitarlo, deberás incluir en la consulta la columna de clave primaria _id en el cursorresultante.

3.2.7. Caché de libros

Tal como se ha comentado en la introducción, usaremos nuestra base de datos local yprivada como una caché de los libros presentes en el servidor remoto, de tal forma que notengamos que obtenerlos de manera remota cada vez que obtengamos el listado. Ahoraque ya has comprobado que los libros obtenidos de la clase Singleton se almacenancorrectamente en la base de datos, y que además se muestran correctamente en el listadode libros gracias al adaptador que hereda de CursorAdapter, vamos a hacer los cambiosnecesarios para que sólo se acceda a la clase SingletonLibros la primera vez que seejecute la actividad Listado.

• En primer lugar modifica el método getLibros de SingletonLibro para que semuestre un Toast cada vez que se obtengan los libros a partir del singleton:

public ArrayList<Libro> getLibros(Context context) {Toast.makeText(context,

"Accediendo a los servicios remotos",Toast.LENGTH_LONG).show();

return libros;}

• Comprueba que cada vez que accedes al listado de libros desde la actividad principalse muestra el Toast.

• Añade un atributo estático booleano a la clase Listado:

public static boolean inicializado = false;

• Utiliza el valor del atributo Listado.inicializado para saber si ya se ejecutóListado al menos una vez (con lo que la base de datos de libros ya contendría loslibros del objeto singleton). Si esto es así no hagas uso del método getLibros deSingletonLibros.

• En el manejador del click sobre un elemento de la lista, haz las modificacionesnecesarias para que el libro se obtenga del cursor que a su vez se obtuve de la base de

Proyecto de Integración

35Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 36: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

datos, en lugar del ArrayList de libros obtenido a partir de SingletonLibros.

Nota:En estos ejercicios no estamos considerando la posibilidad de que la base de datos remota delibros se modifique. Para que este evento puediera ser manejado correctamente deberíamosrecibir alguna notificación del servidor remoto. Simplemente supondremos que no se puedeproducir esta situación.

3.2.8. Alta de libro (*)

La actualización de la base de datos en el caso en el que se añada, elimine o edite un libroes optativa.

Comenzamos por el alta de un libro. Tras dar de alta un libro no sólo deberemos añadirloal listado de libros del objeto singleton sino que también deberemos añadirlo a la base dedatos local de la aplicación. Para ello hacemos uso del método insertar deAdaptadorLibros.

Comprueba que al añadir el libro no se actualiza automáticamente el listado. Es necesariovolver a la actividad principal y volver a mostrar la actividad Listado para podervisualizar en la lista el nuevo libro.

Para que la actualización se lleve a cabo adecuadamente es necesario ejecutar lassiguientes instrucciones al volver de la actividad EditarLibro a Listado, donde items

es el cursor que se obtuvo a partir de la consulta a la base de datos, y la es la instancia deLibroAdapter:

items.requery();la.notifyDataSetChanged();

Nota:Según la API de la SDK de Android el método requery está deprecated. En la documentaciónse aconseja volver a realizar la consulta de nuevo para obtener un nuevo cursor, pero esoconllevaría añadir más código. Puedes hacerlo de esta forma si lo crees conveniente.

3.2.9. Edición de libro (*)

En este ejercicio haremos los cambios necesarios para que la actualización de un libro nosólo se refleje en la base de datos remota (representada por medio de nuestro objetosingleton) sino que también en nuestra base de datos local. Debemos seguir los siguientespasos:

• Añade el método actualizar a AdaptadorLibro:

// Actualización de librospublic boolean actualizar(long fila, Libro libro) {

// Creamos el objeto utilizado para definir el contenido a

Proyecto de Integración

36Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 37: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

actualizarContentValues valoresActualizar = new ContentValues();

// Asignamos valores a las columnas correspondientesvaloresActualizar.put(COLUMNAS[1], libro.getTitulo());valoresActualizar.put(COLUMNAS[2], libro.getAutor());valoresActualizar.put(COLUMNAS[3], libro.getIsbn());valoresActualizar.put(COLUMNAS[4], libro.getNumPaginas());

String where = COLUMNAS[0] + "=" + fila;

// Actualizamos la fila con el índice especificado en la instrucciónanterior

db.update(TABLA, valoresActualizar, where, null);

return true;}

• Añade el código necesario en EditarLibro para actualizar un libro en la base dedatos cuando éste se modifica también en el listado almacenado enSingletonLibros. Seguramente tendrás que ir pasando mediante intents el valor dela clave primaria del libro a modificar desde Listado a VisualizarLibro y desdeVisualizarLibro a EditarLibro.

3.2.10. Borrado de libro (*)

Como último objetivo optativo se propone, si realizaste el ejercicio optativo de borradode la sesión anterior, implementar la operación de borrado a través de la base de datos.Primero añade el siguiente método a AdaptadorLibros:

public int delete(long fila) {String where = COLUMNAS[0] + "=" + fila;return db.delete(TABLA, where, null);

}

Ahora, cuando borres un libro del singleton, bórralo también de la base de datos.

Proyecto de Integración

37Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 38: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

4. Persistencia iOS

4.1. Introducción

En esta sesión del proyecto de integración, y una vez completada la sesión de interfaz deiOS, vamos a aplicar lo estudiado sobre persistencia a nuestra aplicación de libros. Elmétodo de persistencia que aplicaremos será Core Data. Los pasos que realizaremos enesta sesión del proyecto empezarán por diseñar el modelo de datos, continuaremos con ladefinición e implementación de los componentes necesarios para que podamos acceder alos datos y terminaremos creando una nueva fuente de datos basándonos en la actual.

En esta sesión del proyecto no accederemos a los datos de forma remota (usando serviciosweb), por lo que seguiremos usando los mismos datos que se crean en la fuente de datos.

4.2. Ejercicios

Una vez finalizados los ejercicios accederemos a nuestra colección de libros usando loscomponentes de Core Data, por lo que se simplificará la gestión de estos en nuestraaplicación y estos serán persistentes, es decir, no se eliminarán una vez que cerremos laaplicación.

4.2.1. 1) Diseñando el modelo de datos

El primer ejercicio consiste en diseñar el modelo de datos, mediante el cual Core Data sebasará para el acceder a estos y crear internamente el fichero SQLite.

Para crear el fichero del modelo de la base de datos deberemos seguir los siguientespasos:

a) Creamos el modelo de datos dentro de nuestro proyecto de XCode: Pulsamos en File >New File > Core Data > Data Model. Al archivos le ponemos como nombre:ModeloDatos

Proyecto de Integración

38Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 39: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Creando el modelo de datos

b) Diseñamos el modelo de datos. En el proyecto únicamente tendremos una entidad a laque llamaremos Libro, la cual tendrá los siguientes atributos:

• isbn: String• titulo: String• autor: String• fecha: NSDate• paginas: NSInteger• imagen: String• puntuacion: NSInteger• estado: NSInteger

Proyecto de Integración

39Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 40: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Diseño del modelo de datos

c) Para terminar vamos a añadir el Framework de Core Data a nuestro proyecto, para ellopulsamos sobre el nombre del proyecto en el Project navigator y abrimos la pestañaBuild Phases > Link Binary with Libraries, pulsamos sobre "+" y buscamos elframework CoreData.

4.2.2. 2) Creando las subclases de los Managed Object

Una vez que hemos diseñado el modelo de datos vamos a crear la subclase de la entidadLibro para facilitar el acceso a los datos.

Nota:En el proyecto crearemos una subclase de Managed Object para facilitar el acceso a losatributos del libro, también podemos acceder a sus atributos mediante KVO(Key-Value-Observation), o lo que es lo mismo, como si la entidad estuviera representado por undiccionario (NSDictionary).

XCode nos facilita enormemente la creación de las subclases de Managed Object. Paracrearlas simplemente deberemos de seleccionar el fichero del modelo de datos(.xcdatamodel) y después seleccionar la entidad de la que queremos crear la subclase, ennuestro caso Libro.

Una vez seleccionada hacemos seleccionamos del menú principal Editor > Create

Proyecto de Integración

40Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 41: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

NSManagedObject Subclass. XCode nos creará automáticamente una clase llamadaLibro la cual estará compuesta por los atributos de la entidad "Libro" de nuestro modelode datos. Esta clase Libro será la que utilizaremos a la hora de acceder a los objetos detipo Libro dentro de la aplicación. De esta forma evitaremos acceder al Managed Objectusando KVO.

4.2.3. 3) Implementando los componentes de Core Data

En este ejercicio implementaremos todo el entorno de funcionamiento básico de CoreData, todos sus componentes. Para ello modificaremos la clase delegada de nuestraaplicación.

Nota:La programación de la base de Core Data (la implementación de los componentes) se genera deforma automática al crear un proyecto en XCode que use Core Data. En nuestro caso deberemosde escribir el código de forma manual.

Comenzaremos importando la libreria de CoreData.h e incluyendo las siguientespropiedades a la definición de UAAppDelegate (fichero UAAppDelegate.h):

#import <CoreData/CoreData.h>

@property (readonly, strong, nonatomic) NSManagedObjectContext*managedObjectContext;@property (readonly, strong, nonatomic) NSManagedObjectModel*managedObjectModel;@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator*persistentStoreCoordinator;

Ahora implementaremos los siguientes métodos dentro de la clase UAAppDelegate.m.Para simplificar el trabajo, podemos basarnos en el código del ejercicio de Core Data dela sesión 4 de persistencia o desde las plantillas de XCode creando un proyecto nuevoque utilice Core Data.

• - (void)saveContext

• - (NSURL *)applicationDocumentsDirectory

• - (NSPersistentStoreCoordinator *)persistentStoreCoordinator

• - (NSManagedObjectModel *)managedObjectModel

• - (NSManagedObjectContext *)managedObjectContext

Una vez que hemos programado los métodos anteriores arracamos la aplicación y deberáde funcionar correctamente. En el siguiente ejercicio modificaremos la fuente de datos delibros para obtener los datos usando los componentes de Core Data.

4.2.4. 4) Modificando la fuente de datos (primera parte)

Una vez que hemos implementado los componentes de Core Data en la clase delegada de

Proyecto de Integración

41Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 42: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

la aplicación vamos a crear una fuente de datos nueva para usarlos. A la clase de la fuentede datos la llamaremos UAFuenteDatosCoreData.

Una vez creada la clase vamos a copiar todo el código de la clase UAFuenteDatos y lopegamos en la clase nueva. Ahora deberemos de añadir dos propiedades:

• @property (strong, nonatomic) NSManagedObjectContext

*managedObjectContext;

• @property (strong, nonatomic) NSFetchedResultsController

*fetchedResultsController;

La propiedad de tipo NSManagedObjectContext la emplearemos para acceder al contextode Core Data (realizar guardados, borrados y modificaciones) y la propiedad de tipoNSFetchedResultsController para implementar las consultas a la Base de Datos.

Ahora añadimos el siguiente código en el método de inicialización (init) justo debajo dela inicialización de los arrays:

UAAppDelegate *delegate = (UAAppDelegate *)[[UIApplicationsharedApplication] delegate];self.managedObjectContext = delegate.managedObjectContext;

En el código anterior estamos obteniendo el Managed Object de la clase delegada y se loestamos asignando a la propiedad de la fuente de datos.

Ahora vamos a añadir, al final de la clase, el método que nos devolverá un objeto de tipoNSFetchedResultsController que contendrá todos los Managed Object del contexto,es decir, los resultados de la consulta a la base de datos:

- (NSFetchedResultsController *)fetchedResultsController{

if (__fetchedResultsController != nil) {return __fetchedResultsController;

}

// Set up the fetched results controller.// Create the fetch request for the entity.NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];// Edit the entity name as appropriate.NSEntityDescription *entity = [NSEntityDescription

entityForName:@"Libro"inManagedObjectContext:self.managedObjectContext];[fetchRequest setEntity:entity];

// Set the batch size to a suitable number.[fetchRequest setFetchBatchSize:20];

// Edit the sort key as appropriate.NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]

initWithKey:@"titulo"ascending:NO];NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor,

nil];

Proyecto de Integración

42Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 43: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

[fetchRequest setSortDescriptors:sortDescriptors];

// Edit the section name key path and cache name if appropriate.// nil for section name key path means "no sections".NSFetchedResultsController *aFetchedResultsController =[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestmanagedObjectContext:self.managedObjectContext sectionNameKeyPath:nil

cacheName:nil];

aFetchedResultsController.delegate = self;self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;if (![self.fetchedResultsController performFetch:&error]) {

NSLog(@"Unresolved error %@, %@", error, [error userInfo]);abort();

}

return __fetchedResultsController;}

Como podemos ver en el método anterior ejecutamos una consulta sobre la tabla "libro"de nuestra base de datos y devolvemos los resultados dentro de un objeto de tipoNSFetchedResultsController.

Una vez que hemos implementado lo básico para funcionar con el entorno de Core Datavamos a crear nuevos métodos de la fuente de datos que nos facilitarán el acceso a estos.

4.2.5. 5) Modificando la fuente de datos (segunda parte)

Además de los métodos que hemos copiado de la fuente de datos anterior, ahora vamos aañadir cuatro más:

• -(void) actualizaLibrosColeccion

• -(void) agregaLibroAColeccion:(UALibro *) libro

• -(void) borraLibroDeColeccion:(UALibro *) libro

• -(void) actualizaLibro:(UALibro *)libro

El primer método obtendrá los libros de la base de datos y los añadirá al array de libros dela colección, para de esta forma poder seguir utilizando la misma estructura que teníamos.Los otros tres métodos se encargarán de realizar los cambios correspondientes en elcontexto de Core Data y hacerlos persistentes. Con el fin de simplificar el trabajoúnicamente deberéis de completar sólo dos métodos (el de agregar libro y el deactualizar), los otros dos os los proporcionamos a continuación.

-(void) actualizaLibrosColeccion {

for (Libro *libroManagedObject inself.fetchedResultsController.fetchedObjects){

NSLog(@"Cargo libro a mi coleccion:%@",libroManagedObject.titulo);

UALibro *libro = nil;

Proyecto de Integración

43Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 44: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

libro = [[UALibro alloc] init];libro.isbn = libroManagedObject.isbn;libro.titulo = libroManagedObject.titulo;libro.autor = libroManagedObject.autor;libro.imagen = libroManagedObject.imagen;libro.paginas = [libroManagedObject.paginas intValue];libro.estado = [libroManagedObject.estado intValue];libro.puntuacion = [libroManagedObject.puntuacion intValue];[_librosColeccion addObject:libro];

}

}

// Borra un libro de la coleccion-(void) borraLibroDeColeccion:(UALibro *) libro {

// Actualizamos el contexto para que se recargue el listado de librosself.fetchedResultsController = nil;

NSManagedObjectContext *context = [self.fetchedResultsControllermanagedObjectContext];

// Recorremos cada uno de los libros de la coleccion y lo comparamoscon el que

// queremos borrar. Una vez que lo encontramos lo borraremos delcontexto (Core Data)

for (Libro *libroManagedObject inself.fetchedResultsController.fetchedObjects){

if ([libroManagedObject.isbn isEqualToString:libro.isbn]) {

[context deleteObject:libroManagedObject];

// Save the context.NSError *error = nil;if (![context save:&error]) {

NSLog(@"Unresolved error %@, %@", error, [erroruserInfo]);

abort();}

NSLog(@"Borro libro: %@", libro.titulo);

break;}

}

}

Nota:Por simplificar vamos a cambiar el tipo de dato del atributo imagen de la clase UALibro aString para que coincida con la de la clase Libro. Este cambio tendremos que tenerlo encuenta en las controladoras de la aplicación.

Proyecto de Integración

44Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 45: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

4.2.6. 6) Adaptando las controladoras a la nueva fuente de datos (*)

Una vez que tenemos implementada la fuente de datos para que acceda al sistema de CoreData vamos a revisar controladora a controladora con el fin de sustituir la fuente de datosanterior por la nueva. Para ello simplemente deberemos de sustituir UAFuenteDatos porUAFuenteDatosCoreData.

Por último, y para que los cambios que realicemos en nuestra colección de libros serealicen también en la base de datos, deberemos de ejecutar los métodos de inserción,borrado y modificación en donde corresponda dentro de las controladoras.

Los métodos en los que deberemos añadir la llamada a la fuente de datos son lossiguientes:

• Clase UAColeccionViewController, método:- (void)tableView:(UITableView

*)tableView

commitEditingStyle:(UITableViewCellEditingStyle)editingStyle

forRowAtIndexPath:(NSIndexPath *)indexPath

• Clase UANuevoLibroViewController, método:- (void)alertView:(UIAlertView

*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

• Clase UADatosLibroViewController, método:- (IBAction)

puntuacionModificada:(id)sender

• Clase UAEstadoLibroViewController, método:- (void)tableView:(UITableView

*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Nota:Deberemos de tener cuidado con las conversiones de NSNumber a tipo entero y viceversa ya quela clase Libro usa NSNumber y la clase UALibro NSInteger. Recordatorio, para convertirde entero a NSNumber usaremos: [NSNumber numberWithInt:numero], y al revés:[numero intValue]

Una vez hayamos terminado de implementar todos estos cambios podremos arrancar laaplicación y deberá de funcionar correctamente usando Core Data.

Proyecto de Integración

45Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 46: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

5. Servicios Web iOS

5.1. Introducción

En esta sesión del proyecto de integración vamos a aplicar lo estudiado en el módulo deservicios web en nuestro proyecto de biblioteca de libros. También integraremos Twitterposibilitando al usuario publicar un libro en la red social. Usaremos los servicios web dejtech para obtener los libros disponibles para agregar a nuestra colección.

5.2. Ejercicios

Una vez finalizados los ejercicios obtendremos el listado de libros disponibles desde elservicio web de jtech y podremos compartir un libro por Twitter desde la vista del detalledel libro ¡Comenzamos!

5.2.1. 1) Añadimos la clase ImageDownloader y modificamos la clase UALibro

En este primer ejercicio vamos a modificar la clase UALibro añadiéndole un nuevoatributo llamado imagenPortada de tipo UIImage que nos facilitará más adelante la cargaasíncrona de las portadas.

Añadimos al proyecto una clase helper que se encargará de descargar las imágenes de lasportadas. Podemos descargar la clase desde aqui

Ahora modificamos la clase UALibro añadiéndole un nuevo atributo que vamos a llamarimagenPortada que será de tipo UIImage.

5.2.2. 2) Creando la llamada al Servicio Web

En este ejercicio vamos a crear la llamada al servicio web de libros de jtech, para elloañadimos las siguientes líneas de código a la controladora AgregarViewController.m:

NSURL *url = [NSURL URLWithString:@"http://server.jtech.ua.es:8080/jbib-rest/resources/libros"];

NSURLRequest *theRequest = [NSURLRequest requestWithURL: url];NSURLConnection *theConnection = [NSURLConnectionconnectionWithRequest: theRequest delegate: self];

[UIApplication sharedApplication].networkActivityIndicatorVisible =YES;

Ahora deberemos de añadir los objetos necesarios para gestionar la conexión en el ficheroAgregarViewController.h:

@property(nonatomic,retain) NSURLConnection *currentConnection; //conexión

Proyecto de Integración

46Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 47: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

@property(nonatomic,retain) NSMutableData *downloadedData; //datos que sevan descargando

@property(nonatomic,retain) NSMutableDictionary *downloadingImages;//imagenes descargadas

Modficamos ahora el fichero AgregarViewController.m:

// Importamos las librerias necesarias#import "ImageDownloader.h"

// Definimos los synthesize@synthesize currentConnection = _currentConnection;@synthesize downloadedData = _downloadedData;

@synthesize downloadingImages = _downloadingImages;

5.2.3. 3) Añadimos los métodos del protocolo NSURLConnection

Una vez que hemos creado la llamada al servicio web y hemos definido los objetos paragestionarla, vamos a programar los métodos necesarios del protocolo de la claseNSURLConnection. Completamos los siguientes métodos con el código necesario:

#pragma mark - Eventos de la conexion al servicio

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{

// TODO: Añadimos el objeto data al que ya tenemos}

- (void) connection:(NSURLConnection *)connectiondidFailWithError:(NSError *)error{

[UIApplication sharedApplication].networkActivityIndicatorVisible =NO;

self.currentConnection = nil;}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection{

[UIApplication sharedApplication].networkActivityIndicatorVisible =NO;

// TODO: Parseamos el objeto JSON que tenemos en self.downloadedData yrecorremos

// todos los libros añadiéndolos al array de libros de la clase

[self.tableView reloadData];}

5.2.4. 4) Implementamos la carga de imágenes de portada asíncrona

Proyecto de Integración

47Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 48: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

En este punto vamos a implementar la carga de imágenes asíncrona para los libros. Lacarga de imágenes la realizaremos de la siguiente manera: al cargar una celda de la tablacomprobaremos si la imagen de la portada del libro (atributo imagenPortada) no existe,si es así cargaremos la imagen de modo asíncrono. En caso contrario mostraremos laimagen que tenemos en el objeto.

Para implementar este punto añadiremos los dos siguientes métodos al final de lacontroladora UAAgregarViewController:

- (void) imagenCargada: (id) sender {UALibro *libro = [sender object];libro.imagenPortada = [sender image];

[self.tableView reloadData];

}

- (void) cargarImagen: (UALibro *) libro{

if([self.downloadingImages objectForKey: libro.isbn] == nil) {NSString *urlString = [NSStringstringWithFormat:

@"http://server.jtech.ua.es:8080/jbib-rest/resources/libros/%@/imagen",libro.isbn];

ImageDownloader *theDownloader = [[ImageDownloader alloc]initWithUrl:urlStringobject:librotarget:selfselector: @selector(imagenCargada:)];

[self.downloadingImages setValue: theDownloader forKey:libro.isbn];

}}

También deberemos de actualizar el método cellForRowAtIndexPath añadiendo elsiguiente fragmento de código justo antes de return cell;

if (libro.imagenPortada == nil){cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];

// Cargar imagen lazy[self cargarImagen:libro];

}else {

cell.imageView.image = libro.imagenPortada;}

Por último deberemos inicializar el NSMutableDictionary dentro del métodoviewDidLoad, por lo que el método quedaría de la siguiente manera:

- (void)viewDidLoad{

[super viewDidLoad];

NSURL *url = [NSURL URLWithString:

Proyecto de Integración

48Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 49: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

@"http://server.jtech.ua.es:8080/jbib-rest/resources/libros"];NSURLRequest *theRequest = [NSURLRequest requestWithURL: url];NSURLConnection *theConnection = [NSURLConnectionconnectionWithRequest: theRequest delegate: self];

[UIApplication sharedApplication].networkActivityIndicatorVisible =YES;

self.currentConnection = theConnection;self.downloadedData = [NSMutableData data];

self.downloadingImages = [[NSMutableDictionary alloc] init];}

5.2.5. 5) Integrando la carga de imágenes en nuestra colección

Al igual que hemos realizado en el punto anterior, escribiremos el mismo código en lacontroladora UAColeccionViewController para cargar las imágenes de las portadas deforma asíncrona. Esto deberemos hacerlo así porque las imágenes no las almacenamos enla base de datos de Core Data.

LLegados a este punto podemos probar la carga de imágenes asíncrona. Las imágenes sedeben de cargar una sóla vez.

5.2.6. 6) Modificando las vistas de detalle del libro

Si entramos en la vista de detalle de algún libro veremos que la imagen de la portada nose carga, esto es porque debemos de asignar la imagen de la vista (el outlet) al atributoimagenPortada del libro. Para hacer esto deberemos de modificar el código necesario enlas controladoras UANuevoLibroViewController y UADatosLibroViewController.

5.2.7. 7) Integrando Twitter (*)

En este último ejercicio de esta sesión del proyecto integraremos Twitter en nuestraaplicación de la biblioteca. Crearemos un botón en la parte superior derecha de la vistaUADatosLibroViewController en el que cuando pulsemos sobre el nos aparecerá lainterfaz de Twitter de iOS 5 para publicar un Tweet sobre el libro. Para ello realizaremoslos siguientes pasos:

• a) Importamos el framework de Twitter (Twitter.framework) al proyecto.• b) Creamos un botón de tipo UIBarButtonItem con el título "Twitter" y que ejecute

la acción publicarEnTwitter

• c) Añadimos el botón a derecha de la barra de navegación.• d) Implementamos el método publicarEnTwitter para que muestre la interfaz de

Twitter de iOS 5 con un texto predeterminado y la imagen de la portada del libro.

Proyecto de Integración

49Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Page 50: Proyecto de Integración - ua · Puntuación. A la derecha tendrá una etiqueta con la puntuación, y un stepper para modificarla (debe admitir valores de 0 a 10). Ambos elementos

Proyecto de Integración

50Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.