timeline

Implementando una timeline de Twitter con Core Data (Parte I), por @gonzalezreal

Core Data & Servicio Web: mejorando la experiencia de usuario

Si abrimos la aplicación de Twitter para iOS, comprobaremos que muestra la timeline inmediatamente y, tras unos instantes, la actualiza con nuevos tweets. Si hacemos scroll para ver tweets más antiguos, es muy probable que la aplicación los muestre sin necesidad de hacer ninguna petición al servicio. Si abrimos la aplicación de Path o la de Facebook, podemos comprobar que el comportamiento es similar. Todas estas aplicaciones guardan una caché de la timeline del usuario.

Ahora imaginemos que pasaría si esto no fuera así. Cada vez que abriésemos Twitter, la aplicación nos mostraría una pantalla en blanco con un indicador de actividad mientras obtiene nuestros tweets. No podríamos hacer nada hasta que nuestra timeline estuviera actualizada. Es más, si no tuviéramos conexión no podríamos hacer absolutamente nada con la aplicación. Claramente, esto sería una experiencia de usuario poco satisfactoria.

Llevo tiempo queriendo escribir sobre el uso de Core Data con un Servicio Web, y la implementación de una timeline de Twitter me parece el ejemplo más idóneo, ya que demuestra como el uso de una caché mejora drásticamente la experiencia de usuario.

Timeline de Twitter utilizando Core Data y el framework de Twitter para iOS

En esta serie de artículos vamos a desarrollar una aplicación que muestra una timeline de Twitter utilizando Core Data y el framework de Twitter para iOS.

Vamos a ver, entre otras cosas, como hacer el modelo Core Data de una timeline, como transformar un objeto JSON en un objeto de Core Data, como usar el framework de Twitter para obtener tweets, como gestionar el ‘stack’ de Core Data y, finalmente, como implementar un View Controller que gestione el modelo y la presentación de la timeline.

Manos a la obra

Abrimos Xcode 4.5 y creamos un nuevo proyecto, seleccionando la plantilla Master-Detail Application.

Plantilla Master-Detail Application

A continuación configuramos las opciones de nuestro proyecto. Introducimos los campos tal y como se indica en la imagen y nos aseguramos de marcar las opciones Use Storyboards y Use Automatic Reference Counting. Aunque nuestra aplicación va a utilizar Core Data, no vamos a marcar Use Core Data, ya que el código que genera la plantilla no nos va a ser de utilidad.

Opciones del Proyecto

Eliminando lo que no vamos a necesitar

Una vez que el proyecto está creado, borramos algunas cosas que no vamos a necesitar. Abrimos el Storyboard, seleccionamos Master View Controller y Detail View Controller y los borramos.

Borrando ViewControllers en el Storyboard

A continuación seleccionamos los ficheros correspondientes a TGRMasterViewController y TGRDetailViewController y los borramos del proyecto.

Incluyendo los frameworks necesarios

Ya hemos eliminado todo lo que no vamos a utilizar. Ahora toca incluir los frameworks que va a necesitar la aplicación.

En el navegador de proyecto seleccionamos nuestro proyecto. A continuación, en el panel de edición seleccionamos el target TwitterTimeline y la pestaña Build Phases. Expandimos la sección Link Binaries with Libraries, pulsamos sobre el botón ‘+’ y añadimos CoreData.framework.

Repetimos el proceso con los frameworks Accounts.framework y Twitter.framework.

Frameworks necesarios

El modelo de datos

Antes de crear el modelo de datos, vamos a repasar la definición de timeline que hace Twitter:

Una timeline es una colección de tweets y retweets publicados por el usuario autenticado y los usuarios a los que sigue.

Teniendo en cuenta esta definición, nuestro modelo de datos va a tener 2 entidades: Tweet y Usuario, entre las que se establecen las siguientes relaciones:

  • Un tweet ha sido escrito por un usuario.
  • Un tweet ha sido re-tuiteado por un usuario.

Ya tenemos claro como va a ser nuestro modelo de datos, ahora vamos a crearlo. Para ello comenzamos añadiendo un nuevo fichero al proyecto, seleccionamos Data Model como plantilla e introducimos ‘Twitter’ como nombre del fichero.

Continuamos creando la entidad que representa a un tweet. Para ello pulsamos sobre ‘Add Entity’ en el modelo de datos. Introducimos TGRTweet como nombre de la entidad y también de la clase. Es importante que la entidad y la clase tengan el mismo nombre, en el próximo artículo comprobaréis el motivo.

Ahora vamos a crear la entidad que representa a un usuario. Pulsamos de nuevo sobre ‘Add Entity’ en el modelo de datos e introducimos TGRTwitterUser como nombre de la entidad y de la clase.

Relaciones

A continuación vamos a crear y configurar las relaciones entre las 2 entidades. Primero nos aseguramos que el editor está en modo Graph Editor Style.

Seleccionamos TGRTweet y pulsamos sobre el botón ‘Add Attribute’ hasta que aparezca el menú de contexto y seleccionamos ‘Add Relationship’.

Introducimos ‘user’ como nombre de la relación y seleccionamos TGRTwitterUser como destino. Los demás valores los dejamos por defecto.

Ahora vamos a crear la relación inversa. Seleccionamos TGRTwitterUser en el diagrama y pulsamos sobre el botón ‘Add Relationship’. Introducimos ‘tweets’ como nombre de la relación, seleccionamos TGRTweet como destino y ‘user’ como relación inversa. Además marcamos la opción ‘Plural’, ya que esta relación es de uno a muchos, y seleccionamos ‘Cascade’ como regla de borrado.

Ya tenemos las entidades relacionadas de tal manera que un tweet tiene un usuario y un usuario puede tener muchos tweets. Ahora vamos a establecer las relaciones para soportar retweets.

Seleccionamos la entidad TGRTweet y añadimos una relación con el nombre ‘retweetedBy’, seleccionando TGRTwitterUser como destino.

Vamos a crear la relación inversa. Seleccionamos la entidad TGRTwitterUser y añadimos una relación con el nombre ‘retweets’. Seleccionamos TGRTweet como destino y ‘retweetedBy’ como relación inversa. Además marcamos la opción ‘Plural’, ya que esta relación es de uno a muchos.

Si habéis seguido todos los pasos correctamente vuestro diagrama debería ser parecido al que muestra la siguiente imagen.

Atributos

Antes de añadir los atributos de ambas entidades, repasemos lo que se muestra típicamente en un tweet dentro de una timeline.

Por un lado tenemos el texto y la fecha de publicación como atributos del tweet. En lo que respecta al usuario, tenemos la URL de la imagen de perfil, el nombre y el pseudónimo. Además, cada tweet y usuario poseen un identificador único.

Vamos a comenzar añadiendo los atributos de TGRTweet. Seleccionamos TGRTweet en el modelo y añadimos un atributo nuevo. Introducimos ‘identifier’ como nombre del atributo. Marcamos ‘indexed’ ya que es posible que queramos realizar búsquedas de tweets por identificador. Finalmente seleccionamos ‘String’ como tipo de atributo.

Añadimos otro atributo nuevo para guardar la fecha de publicación. Introducimos ‘publicationDate’ como nombre de atributo y ‘Date’ como tipo.

Por último añadimos el atributo para guardar el texto del tweet. Introducimos ‘text’ como nombre de atributo y ‘String’ como tipo.

Ahora vamos a añadir los atributos de TGRTwitterUser. Seleccionamos TGRTwitterUser en el modelo y añadimos un atributo nuevo. Introducimos ‘identifier’ como nombre del atributo. Al igual que con un tweet, vamos a necesitar realizar búsquedas de usuario por identificador, por lo que marcamos la opción ‘indexed’. Finalmente seleccionamos ‘String’ como tipo de atributo.

Continuamos añadiendo un atributo para guardar el nombre del usuario. Introducimos ‘name’ como nombre de atributo y ‘String’ como tipo.

Añadimos otro atributo para guardar el pseudónimo del usuario. Introducimos ‘screenName’ como nombre de atributo y ‘String’ como tipo.

Por último, añadimos un atributo para guardar la URL de la imagen de perfil del usuario. Introducimos ‘imageLink’ como nombre de atributo y ‘String’ como tipo.

El modelo terminado

Nuestro modelo terminado quedaría como se muestra en la siguiente imagen.

Generando código

Con el modelo terminado estamos listos para generar las clases correspondientes a las entidades que acabamos de diseñar.

Para ello pulsamos con el botón derecho sobre la carpeta TwitterTimeline en el navegador del proyecto y seleccionamos ‘New File…’.

A continuación seleccionamos la plantilla ‘NSManagedObject subclass’ y pulsamos sobre el botón ‘Next’. Aparecerá una lista con las entidades de nuestro modelo.

Marcamos todas las entidades, pulsamos sobre ‘Next’ y confirmamos la creación pulsando sobre ‘Create’.

Ya tenemos las bases de nuestro modelo de datos. El código fuente correspondiente a lo que hemos hecho lo podéis encontrar aquí.

En el próximo artículo veremos como implementar una clase Timeline que encapsule las llamadas al API de Twitter y la creación de objetos TGRTweet y TGRTwitterUser a partir del JSON recibido.

Mientras tanto, si tenéis preguntas o comentarios podéis encontrarme en Twitter como @gonzalezreal.

Acerca del autor

Guillermo González, artesano del software, amante de los cómics y aficionado al cine. Líder de desarrollo móvil para PopCha! Podéis encontrarme en Twitter como @gonzalezreal.

Acerca de Guillermo González Real

Artesano del software, amante de los cómics y aficionado al cine. Líder de desarrollo móvil para PopCha!

Share this: