Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1. Índice de figuras II
2. Introducción 1
5. Recursos e infraestructura 12
5.1. Software para Desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.2. Software en el Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6. Tecnologı́as 14
6.1. Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.2. Móviles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.3. Comunicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
8. Análisis funcional 18
8.1. Requerimientos funcionales . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
8.1.1. Descripción básica del funcionamiento . . . . . . . . . . . . . . . . . 18
8.1.2. Interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
8.1.3. Particularidades de la versión móvil . . . . . . . . . . . . . . . . . . 19
8.1.4. Uso de caracterı́sticas de los dispositivos iOS . . . . . . . . . . . . . 19
8.2. Funcionalidades del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . 19
I
8.2.1. Plataforma móvil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
8.2.2. Plataforma web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
8.3. Usuarios del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
8.4. Casos de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
8.4.1. Descripción caso de uso [CL00] Reservar Taxi . . . . . . . . . . . . 22
8.4.2. Descripción caso de uso [CL01] Pedir Taxi . . . . . . . . . . . . . . 22
8.4.3. Descripción caso de uso [CL02] Ver Disponibilidad . . . . . . . . . . 23
8.4.4. Descripción caso de uso [CL03] Valorar Servicio . . . . . . . . . . . 23
8.4.5. Descripción caso de uso [TA00] Iniciar Sesión . . . . . . . . . . . . 24
8.4.6. Descripción caso de uso [TA01] Finalizar Sesión . . . . . . . . . . . 24
8.4.7. Descripción caso de uso [TA02] Ver Reputación . . . . . . . . . . . 25
8.4.8. Descripción caso de uso [TA03] Aceptar Servicio . . . . . . . . . . . 25
8.4.9. Descripción caso de uso [TA04] Cómo Llegar . . . . . . . . . . . . . 26
8.4.10. Descripción caso de uso [AD00] Gestionar Taxistas . . . . . . . . . 26
9. Diseño técnico 27
9.1. Arquitectura plataforma web . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.2. Arquitectura plataforma móvil . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.3. Arquitectura fı́sica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.4. Arquitectura lógica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.4.1. Arquitectura lógica de la plataforma móvil . . . . . . . . . . . . . . . 29
9.4.2. Arquitectura iOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
9.4.3. Arquitectura lógica de la plataforma web . . . . . . . . . . . . . . . . 31
9.4.4. Arquitectura lógica de intercambio de información entre plataformas 32
9.5. Arquitectura de componentes . . . . . . . . . . . . . . . . . . . . . . . . . . 32
9.6. Arquitectura de base de datos . . . . . . . . . . . . . . . . . . . . . . . . . 33
9.6.1. Modelo entidad-relación de la base de datos . . . . . . . . . . . . . 33
9.6.2. Entidad taxi drivers . . . . . . . . . . . . . . . . . . . . . . . . . . 34
9.6.3. Entidad taxi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
9.6.4. Entidad rides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
9.6.5. Entidad assignments . . . . . . . . . . . . . . . . . . . . . . . . . . 35
9.6.6. Entidad ratings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
9.7. Diagrama de clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
9.7.1. Clases de la plataforma móvil (capa de presentación) . . . . . . . . 37
9.7.2. Clases de la plataforma móvil (capa de negocio) . . . . . . . . . . . 38
9.7.3. Clases de la plataforma web (capa de negocio) . . . . . . . . . . . . 39
9.7.4. Clases de la plataforma web (capa de presentación) . . . . . . . . . 40
9.8. Diagrama de secuencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
9.8.1. Diagrama de secuencia – Ejemplo ver disponibilidad . . . . . . . . . 40
II
10. Prototipo 42
10.1.Pantalla de inicio (cliente) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
10.2.Pantalla de solicitar taxi (cliente) . . . . . . . . . . . . . . . . . . . . . . . . 44
10.3.Pantalla de disponibilidad (cliente) . . . . . . . . . . . . . . . . . . . . . . . 45
10.4.Pantalla de inicio con servicio (cliente) . . . . . . . . . . . . . . . . . . . . . 46
10.5.Pantalla de inicio de sesión (taxista) . . . . . . . . . . . . . . . . . . . . . . 47
10.6.Pantalla inicial (taxista) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
10.7.Pantalla de reputación (taxista) . . . . . . . . . . . . . . . . . . . . . . . . . 49
10.8.Pantalla de solicitud de servicio (taxista) . . . . . . . . . . . . . . . . . . . . 50
10.9.Pantalla de servicio en curso (taxista) . . . . . . . . . . . . . . . . . . . . . 51
11. Implementación 52
11.1.Caracterı́sticas principales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
11.1.1. Facilidad de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
11.1.2. Rapidez de respuesta . . . . . . . . . . . . . . . . . . . . . . . . . . 52
11.1.3. Multiples idiomas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
11.1.4. Legibilidad del código fuente . . . . . . . . . . . . . . . . . . . . . . 53
11.2.Plataforma web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
11.3.Plataforma móvil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
11.3.1. App Taxista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
11.3.2. App Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
13. Conclusiones 75
13.1.Cumplimiento de los objetivos propuestos . . . . . . . . . . . . . . . . . . . 75
III
13.2.Valoración personal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
13.3.Futuras mejoras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
IV
1 Índice de figuras
V
12.5.App Cliente: notificación taxi en camino, con la app cerrada y abierta . . . . 64
12.6.App Cliente: taxi en camino . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
12.7.App Cliente: notificación taxi llegando, con la app cerrada y abierta . . . . . 65
12.8.App Cliente: estados de un servicio - pendiente, taxista en camino, iniciado 66
12.9.App Cliente: notificación finalización servicio, con la app cerrada y abierta . 67
12.10.App Cliente: puntuar último servicio . . . . . . . . . . . . . . . . . . . . . . 67
12.11.App Taxista: icono, splash y pantalla de login . . . . . . . . . . . . . . . . . 68
12.12.App Taxista: iniciar sesión con error . . . . . . . . . . . . . . . . . . . . . . 68
12.13.App Taxista: iniciar sesión con éxito . . . . . . . . . . . . . . . . . . . . . . 69
12.14.App Taxista: actualizar disponibilidad . . . . . . . . . . . . . . . . . . . . . . 69
12.15.App Taxista: notificación nuevo servicio asignado, con la app cerrada y
abierta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
12.16.App Taxista: rechazar servicio . . . . . . . . . . . . . . . . . . . . . . . . . . 71
12.17.App Taxista: aceptar servicio . . . . . . . . . . . . . . . . . . . . . . . . . . 71
12.18.App Taxista: cómo llegar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
12.19.App Taxista: finalizar servicio . . . . . . . . . . . . . . . . . . . . . . . . . . 72
12.20.App Taxista: ver reputación . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.21.App Taxista: cerrar sesión . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
VI
2 Introducción
Una idea ası́ de simple es el origen de este proyecto. La posibilidad de pedir un taxi
simplemente pulsando un “botón”, sin necesidad de saber la dirección donde uno se
encuentra.
1
3 Definición General del Proyecto
Esa idea tan simple tiene muchas implicaciones. Para que al pulsar un botón se pida un
taxi, se necesita lo siguiente:
Para solventar estas necesidades, el proyecto deberá incluir una plataforma que los taxis-
tas puedan utilizar (lo que cubre la segunda necesidad). Esta plataforma se encargará de
recibir las peticiones y asignarlas al taxi más adecuado (con lo que también se cubre la
primera necesidad).
3.1. Objetivos
Para cumplir los objetivos la aplicación deberı́a proporcionar las siguientes funcionalida-
des:
Pedir un taxi: permitir a un usuario solicitar un taxi para el lugar donde se encuentre
Reservar un taxi: permitir a un usuario solicitar un taxi para la hora y lugar que
desee
2
PFC: Taxi! 3. Definición General del Proyecto
Cuánto falta: dar al usuario el tiempo estimado para la llegada del taxi
Cómo llegar: indicar a un taxista la dirección del cliente y permitirle obtener la ruta
más apropiada
Por el tipo de producto que se generará en el proyecto podrı́a ser más apropiada una
planificación utilizando metodologı́as ágiles como las explicadas en otras asignaturas.
De todas formas, se emplearán ciertos aspectos de dichas metodologı́as allı́ donde sea
posible, siempre respetando la planificación indicada.
Los hitos del proyecto según la planificación especificada en el plan docente son:
4.2. Calendario
Fijando la fecha de entrega final como fecha lı́mite (10 de Junio), y asignando hitos
para cada una de las entregas parciales, propongo el calendario descrito en el siguiente
diagrama de Gantt:
4
PFC: Taxi! 4. Calendario del Proyecto
Se dispone de 102 dı́as para realizar el proyecto (en el diagrama aparecen 161 dı́as
de “esfuerzo”, causados por tener tareas que transcurren en paralelo y no haber podido
asignar una dedicación parcial a cada una de ellas). Se consideran como hábiles los fines
de semana y festivos, habida cuenta que probablemente sean éstos los más aprovecha-
bles para avanzar el desarrollo del proyecto. Las tareas de diferentes grupos están en
distintos colores para facilitar su identificación. Las tareas en gris claro (Pruebas unitarias
y de integración) se realizarán simultáneamente a la implementación, debido a que se
utilizará el paradigma Behaviour Driven Development según el cual se escribirán los tests
de aceptación antes de escribir el código que implemente dicha funcionalidad.
Ordenador de desarrollo: MacBook Pro 15” (Intel Core 2 Duo 2,8GHz, 8 GB RAM
DDR3), OS X 10.8.2 - 10.8.4
Software Función
Xcode Entorno de desarrollo para la aplicación móvil
(Objective-C)
Textmate Editor de texto para desarrollar la aplicación
web (Ruby on Rails) y otros scripts de soporte
Byword Herramienta para la redacción en Markdown
de los documentos a entregar
Omniplan Herramienta para la gestión de proyectos y
preparación de diagramas de Gantt
Acorn Software para el retoque de imágenes
Dropbox Para copia de seguridad del código fuente y
documentos
Github Servicio web para almacenar los repositorios
del código fuente de ambas plataformas y de
la documentación
12
PFC: Taxi! 5. Recursos e infraestructura
Software Función
nginx Servidor web que recibirá las peticiones web y
las distribuirá al servidor de aplicaciones
unicorn Servidor de aplicaciones basado en eventos
para Ruby on Rails
MySQL Base de datos para almacenar las peticiones,
los taxis y las coordenadas
grocer Software para comunicación con servidores de
Apple para notificaciones Push a los
dispositivos móviles
El proyecto se divide en dos partes bien diferenciadas: un servicio web que recibe peti-
ciones de usuarios, asigna el taxi a utilizar y notifica a los interesados, y una app móvil
con la que interactuarán directamente los actores.
6.1. Web
El servidor web alojará una aplicación Ruby on Rails que implementará los servicios
REST con los que se comunicará la aplicación móvil. Almacenará en la base de datos
MySQL la posición GPS de cada uno de los taxis disponibles, y cuando un cliente solicite
un taxi detectará el más cercano a la posición del cliente y se lo notificará. Estas notifi-
caciones utilizarán la tecnologı́a Push disponible en la plataforma de Apple para que los
usuarios reciban los avisos aunque la aplicación móvil esté cerrada.
6.2. Móviles
6.3. Comunicaciones
14
PFC: Taxi! 6. Tecnologı́as
Object Notation). Se trata de tecnologı́as mucho más simples y eficientes que SOAP y
XML para la naturaleza de las comunicaciones a utilizar.
Para las notificaciones Push, el servidor web se comunicará con la plataforma de notifi-
caciones de Apple encargados de distribuir las notificaciones a los dispositivos utilizando
también REST y JSON. Los dispositivos recibirán las notificaciones con el mensaje JSON
indicado por el servidor web a la plataforma de notificaciones de Apple.
A continuación se muestra una tabla con una serie de riesgos identificados para el éxito
del proyecto:
16
PFC: Taxi! 7. Riesgos del Proyecto
En esta sección se detallarán los requisitos del sistema y los casos de uso para ofrecer
una visión global de la solución propuesta.
El sistema tiene como finalidad permitir la comunicación entre taxistas y clientes de ca-
ra a realizar solicitudes de servicio, evitando al cliente la necesidad de saber dónde
está exactamente, o el nombre de la calle. Para cumplir este objetivo, contará con las
funcionalidades descritas a continuación.
La aplicación debe cubrir la funcionalidad básica de poder pedir un taxi de la forma más
sencilla posible. Para poder cumplir esta funcionalidad debe permitir:
Pedir o reservar un taxi: permitir a un usuario solicitar un taxi para la hora y el lugar
que indique
8.1.2. Interfaz
18
PFC: Taxi! 8. Análisis funcional
Para poder realizar la comunicación entre clientes y taxistas, se necesita de una plata-
forma web que haga de intermediario, reciba los mensajes y notifique a los interesados.
Esta plataforma web podrı́a tener funcionalidades avanzadas, como la posibilidad de
asignar manualmente un servicio a un taxista o consultar estadı́sticas e informes, pe-
ro en el ámbito de este proyecto simplemente consistirá en proveer servicios web a la
aplicación móvil y una simple interfaz para registrar taxistas en el sistema.
La aplicación móvil utilizará las caracterı́sticas que ofrece el entorno de desarrollo de iOS
para utilizar los recursos del dispositivo. Se utilizará tanto el módulo GPS presente en
cada iPhone como la conectividad a red. Debido al tipo de uso que tendrá la aplicación,
dicha conectividad será principalmente vı́a 3G.
En este caso, existe una discrepancia en el uso tı́pico del GPS que necesita hacer la
aplicación según el usuario. Si se trata de un cliente, se puede asumir que irá a pie,
por lo que el GPS puede estar apagado gran parte del tiempo, sólo activándose en el
momento de iniciar una solicitud. En cambio, para el caso del taxista el GPS tiene que
estar activo con mucha más frecuencia para que pueda notificar su posición al servidor,
y dicha información ha de tener la mayor vigencia posible.
Pedir un taxi: permitir a un usuario solicitar un taxi para el lugar donde se encuentre
Reservar un taxi: permitir a un usuario solicitar un taxi para la hora y lugar que
desee
Cuánto falta: dar al usuario el tiempo estimado para la llegada del taxi
Cómo llegar: indicar a un taxista la dirección del cliente y permitirle obtener la ruta
más apropiada
La plataforma web tiene como funcionalidad principal el hacer de nexo de unión entre
clientes y taxistas, recibiendo comunicaciones de la aplicación móvil y enviando notifi-
caciones a los usuarios. Para realizar estas tareas implementará una interfaz REST que
permitirá a la aplicación móvil realizar sus operaciones.
App Móvil Clientes Finales, usuarios de la App Móvil Taxistas, y usuarios del módulo de
gestión de la plataforma web:
Cliente: representa a aquellos usuarios que interactúan con la aplicación móvil para
clientes.
Taxista registrado: representa a aquellos usuarios que han sido dados de alta en el
sistema como taxistas.
Iniciar Sesión
Valorar
Servicio
Finalizar
Sesión Taxista
Reservar Taxi Registrado
Cliente
<extiende> Ver
Reputación
Pedir Taxi
<extiende> Asignar
Servicio
<usa>
Taxista
Identificado
<extiende>
<usa>
Aceptar
Ver Servicio
Disponibilidad
<usa>
<usa>
<usa>
Cómo Llegar
Gestionar
Taxistas
Administrador
Identificador CL00
Nombre Reservar Taxi
Resumen El cliente reserva un taxi para un lugar y una
hora determinados
Actores Cliente
Precondiciones El cliente ha iniciado la aplicación
Postcondiciones El cliente ha enviado una solicitud
Flujo normal 1. El cliente pulsa sobre el botón de pedir taxi -
2. El cliente selecciona una ubicación - 3. El
cliente selecciona una hora - 4. El cliente
pulsa sobre el botón pedir para confirmar
Flujos alternativos 4b. El cliente pulsa sobre el botón volver y
cancela la petición
Inclusiones SY00 Mostrar Mapa
Extensiones Asignar Servicio
Identificador CL01
Nombre Pedir Taxi
Resumen El cliente reserva un taxi en su ubicación
actual para ese mismo momento
Actores Cliente
Precondiciones El cliente ha iniciado la aplicación
Postcondiciones El cliente ha enviado una solicitud
Flujo normal 1. El cliente pulsa sobre el botón de pedir taxi -
2. El cliente pulsa sobre el botón pedir para
confirmar
Flujos alternativos 2b. El cliente pulsa sobre el botón volver y
cancela la petición
Inclusiones SY00 Mostrar Mapa
Extensiones Asignar Servicio
Identificador CL02
Nombre Ver Disponibilidad
Resumen Este caso de uso indica cómo el cliente puede
comprobar los taxis disponibles en un
momento dado
Actores Cliente
Precondiciones El cliente ha iniciado la aplicación
Postcondiciones El cliente ha visto los taxis disponibles
Flujo normal 1. El cliente pulsa sobre el botón ver
disponibilidad - 2. Se visualizan los taxis
disponibles sobre el mapa - 3. El cliente pulsa
sobre el botón volver
Flujos alternativos -
Inclusiones SY00 Mostrar Mapa
Extensiones Ninguno
Identificador CL03
Nombre Valorar Servicio
Resumen Este caso de uso indica cómo el cliente puede
valorar un servicio recibido
Actores Cliente
Precondiciones El cliente ha recibido un servicio
Postcondiciones El cliente ha valorado el servicio o ha
declinado hacerlo
Flujo normal 1. El sistema notifica al cliente que el servicio
ha finalizado - 2. El cliente pulsa sobre el
botón valorar - 3. El cliente introduce su
puntuación de 1 a 5 - 4. El cliente pulsa sobre
el botón aceptar
Flujos alternativos 2b. El cliente pulsa sobre el botón declinar -
4b. El cliente pulsa sobre el botón cancelar
Inclusiones Ninguno
Extensiones Ninguno
Identificador TA00
Nombre Iniciar Sesión
Resumen Caso de uso que muestra cómo un taxista
inicia sesión
Actores Taxista Registrado
Precondiciones El usuario no ha iniciado sesión
Postcondiciones El usuario ha iniciado sesión
Flujo normal 1. El cliente rellena el formulario y pulsa sobre
el botón iniciar sesión - 2. El sistema valida los
datos del usuario, si son correctos activa la
sesión del usuario y muestra el menú principal
Flujos alternativos 1b. El usuario cierra la aplicación - 2b. Si los
datos no son correctos se muestra el
formulario de nuevo
Inclusiones Ninguno
Extensiones Ninguno
Identificador TA01
Nombre Finalizar Sesión
Resumen Caso de uso que muestra cómo un taxista
finaliza sesión
Actores Taxista Identificado
Precondiciones Un taxista ha iniciado sesión
Postcondiciones No hay sesión activa
Flujo normal 1. El cliente pulsa sobre el botón salir - 2. En la
ventana de confirmación, el cliente pulsa
sobre el botón confirmar
Flujos alternativos 2b. El cliente pulsa sobre el botón cancelar y
sigue con su sesión activa
Inclusiones Ninguno
Extensiones Ninguno
Identificador TA02
Nombre Ver Reputación
Resumen Este caso de uso indica cómo el taxista puede
consultar su reputación
Actores Taxista Identificado
Precondiciones Un taxista ha iniciado sesión
Postcondiciones -
Flujo normal 1. El taxista pulsa sobre el botón ver
reputación - 2. Se muestra la puntuación
media de sus valoraciones en pantalla
Flujos alternativos -
Inclusiones Ninguno
Extensiones Ninguno
Identificador TA03
Nombre Aceptar Servicio
Resumen Este caso de uso indica cómo el taxista puede
aceptar un servicio
Actores Taxista Identificado
Precondiciones Un taxista ha iniciado sesión
Postcondiciones El servicio ha sido aceptado y el cliente
notificado
Flujo normal 1. El sistema notifica al taxista del servicio
asignado - 2. El taxista pulsa sobre el botón
aceptar - 3. El sistema notifica al cliente
Flujos alternativos 2b. El taxista pulsa sobre el botón rechazar, el
sistema selecciona otro taxista y le notifica
Inclusiones SY00 Mostrar Mapa
Extensiones TA04 Cómo Llegar
Identificador TA04
Nombre Cómo Llegar
Resumen Este caso de uso indica cómo el taxista puede
consultar una ruta al cliente
Actores Taxista Identificado
Precondiciones El taxista tiene un servicio aceptado en curso
Postcondiciones El taxista obtiene una ruta para llegar al cliente
Flujo normal 1. El taxista pulsa sobre el botón cómo llegar -
2. Se abre la aplicación de mapas nativa con
la ruta ya introducida
Flujos alternativos -
Inclusiones SY00 Mostrar Mapa
Extensiones Ninguno
Identificador AD00
Nombre Gestionar Taxistas
Resumen Caso de uso de alto nivel que explica cómo el
administrador añade taxistas en el sistema
Actores Administrador
Precondiciones El administrador ha abierto el sistema
Postcondiciones El taxista ha sido añadido
Flujo normal 1. El administrador pulsa sobre el botón añadir
taxista - 2. El administrador rellena los datos
del taxista en el formulario y le asigna una
contraseña - 3. El administrador pulsa sobre el
botón guardar
Flujos alternativos 3b. El administrador pulsa sobre el botón
cancelar y sale del formulario
Inclusiones Ninguno
Extensiones Ninguno
Servidor web: nginx - recibe las peticiones de de los clientes vı́a internet
La plataforma web responderá tanto a las peticiones de los clientes mediante servicios
web como a las peticiones del administrador.
27
PFC: Taxi! 9. Diseño técnico
En este caso, la aplicación cliente estará implementada para el sistema operativo iOS de
Apple, en concreto para teléfonos móviles iPhone (no habrá versión adaptada para ta-
bletas), utilizando los frameworks proporcionados por Apple y englobados con el nombre
Cocoa Touch.
Además, se hará uso de la infraestructura de servidores push de Apple para poder recibir
las notificaciones del servidor sin obligar a tener abierta la aplicación permanentemen-
te.
Ası́ pues se utilizará un servidor accesible desde internet para realizar el desarrollo,
distinto del servidor de producción donde se alojará definitivamente.
Facilita el evitar repetir código innecesariamente (paradigma conocido por sus ini-
ciales DRY, de Don’t Repeat Yourself o No te repitas)
Debido a las diferentes necesidades de los usuarios de la plataforma móvil (clientes fina-
les y taxistas), se separará la aplicación cliente en dos aplicaciones especı́ficas, en aras
de una mejor usabilidad y simplicidad de uso. Además, hacerlo de esta forma permite te-
ner caracterı́sticas de uso de los recursos diferentes para cada aplicación, adaptándose
mejor a las necesidades de cada usuario.
Un ejemplo de esta mejor flexibilidad se halla en el uso del GPS, pues se puede asumir
que el cliente final irá a pie cuando realice una solicitud, y no será necesario tenerlo
activo constantemente. En cambio, para un taxista sı́ que es conveniente tenerlo activo
más a menudo para poder notificar su posición más frecuentemente al servidor; además,
se puede asumir que el incremento en gasto de la baterı́a por usar más el GPS no es
tan problemático dado que los taxistas pueden mantener cargado el teléfono en el propio
taxi.
Si bien lo habitual es utilizar una arquitectura de 3 capas, consistente en tener una capa
de presentación, una capa de negocio, y una capa de acceso a datos, en el caso de
aplicaciones para iOS se tiende a fusionar la capa de negocio y la capa de acceso a
datos, implementando ambas en los modelos de MVC. No obstante, esto conlleva una
excesiva aumento de las responsabilidades de los modelos, por lo que sigue siendo
conveniente mantener capas separadas.
Una de las particularidades de MVC en Cocoa es que existen objetos que combinan
dos de los roles; uno de los más utilizados es el ViewController, que se tratarı́a de un
controller que se ocupa principalmente de la capa de vista. Su responsabilidad principal
es gestionar la interfaz y comunicarse con el modelo. Son la principal herramienta para
gestionar la interacción con el usuario.
DRY – “Don’t Repeat Yourself” – escribir el mismo código una y otra vez es malo
El mejor patrón para aplicaciones web es REST – utilizar recursos y verbos HTTP
estándar es la forma más rápida de desarrollar.
Routing
1. URL
1 2. El enrutador localiza el
controlador
2 3. El controlador interactúa
con el modelo
4. El controlador invoca a la
Controller vista
5. La vista renderiza la
siguiente pantalla del
3 navegador
4
5
Active
View Record
Model Database
Vistas - se trata comúnmente de ficheros HTML con código Ruby incrustado que
realiza tareas exclusivamente relacionadas con la presentación de los datos. Las
vistas proporcionan los datos al navegador web o a quien esté realizando peticio-
nes a la aplicación.
Plataforma
Móvil (Cliente)
ViewControllers Modelos
API Client
Vistas Frameworks
Plataforma Web
Plataforma
Móvil (Taxi) Modelos
API REST
ActiveRecord
Vistas Frameworks
API Client
ViewControllers Modelos
Por lo que respecta a la plataforma web, cuando es el momento de enviar una notifica-
ción push lo hace directamente la capa de lógica de negocio, sin pasar por el servidor
HTTP.
La base de datos del sistema gestiona los datos de los taxistas, la ubicación de cada taxi
en tiempo real, y el histórico de servicios solicitados, asignados y realizados. El modelo
entidad-relación se define a continuación
#
$
% %&-
%
)*+
!"! (
)*+
,'
!"! #
%
%
(
!"!
!"!
!"!
!"!
%
#
&'( !"!
$ !"!
)*+
% !"!
(
)*+
!"!
!"!
!"!
!"!
!"!
!"!
Entidad Descripción
taxi drivers Almacena los datos del usuario taxista
taxis Almacena los datos actuales del taxi: posición,
disponibilidad. . .
rides Almacena información sobre un servicio: hora,
lugar, dispositivo que ha realizado la
petición. . .
assignments Almacena el histórico de asignaciones de un
servicio a taxistas, y sus respuestas
respectivas hasta que uno lo acepte
ratings Almacea las valoraciones de los clientes sobre
los servicios prestados
admins Almacena los datos del usuario administrador
del sistema
Taxi
TaxiLoginViewController TaxiReputationViewController
Modelos
TaxiMainViewController
TaxiRideViewController
TaxiAssignmentViewController
MKMapViewController
Cliente
TaxiLocationDelegate
CustomerMainViewController
Modelos
MKMapViewController
Taxi
Taxi Reputation
TaxiLocationDelegate TaxiAPIClient
Ride Assignment
Cliente
Ride Taxi
Request TaxiAPIClient
TaxiDriver
add_taxi
1
1
Taxi
Rating closest_taxis
* 1
distance_to
1 1 1
1 * 1
Ride Assignment
assign_taxi accept_assignment
begin 1 * reject_assignment
end notify_taxi_driver
rate notify_customer
<<usa>> <<usa>>
Notification
send
CustomerAPI
available_taxis
hail_taxi
schedule_pickup
assigned_taxi
requested_ride
unrated
rate
Lógica de
TaxiAPI negocio
login
logout
taxi_information
update_position
update_availability
update_device_id
accept_ride
reject_ride
begin_ride
end_ride
assignment_information
ride_information
reputation
Usuario CustomerMainView SystemFrameworks TaxiAPIClient CustomerAPI (web) Taxi < ActiveRecord::Base MySQL
Controller (web)
1. Ver disponibilidad
2. Crea
Availability
2. Crea MKMapViewCont
roller
3. getAvailableTaxis
4. getCurrentPosition
7. getAvailableTaxis
8. filterAvailability
5. locations 9. SELECT ...
6. center
11. Array 10. Array
12. JSON
13. JSON
14. drawAnnotations
Estas pantallas se han desarrollado sobre Xcode, utilizando la herramienta visual Interfa-
ce Builder integrada que ofrece ayuda a la hora de insertar elementos y alinearlos según
las recomendaciones de Apple para Interfaces de Usuario en iOS1 . También se ha uti-
lizado la funcionalidad de Storyboards para realizar las transiciones entre pantallas sin
tener que implementar código.
Se valoraron otras opciones para desarrollar las pantallas como por ejemplo FluidUI2 o
usar plantillas con elementos de la interfaz de iOS en Photoshop, pero estas opciones, a
pesar de permitir diseños más elaborados, no ofrecı́an ningún tipo de asistencia a la hora
de respetar los márgenes o ofrecer ayuda al colocar los elementos de la interfaz.
1
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/
Introduction/Introduction.html
2
https://www.fluidui.com
42
PFC: Taxi! 10. Prototipo
Esta pantalla es la primera que aparece al abrir la aplicación de cliente y permite acceder
a las funcionalidades más importantes de la aplicación:
El botón “Pedir Taxi” permite solicitar un taxi en el lugar y momento que indique el
usuario
El botón con el icono de flecha centra el mapa en la posición actual del usuario
Esta pantalla cambiará su aspecto cuando haya un servicio en curso, como se verá pos-
teriormente.
Para cambiar el momento para el que se desea el taxi se puede elegir entre las tres
opciones en el selector: “ahora”, “en 1 hora”, “en 2 horas”.
Finalmente, el botón “Cancelar” cierra la pantalla sin realizar la reserva, mientras que el
botón “Pedir” confirma la solicitud en el sistema.
Esta pantalla visualiza sobre el mapa la ubicación actual, y un icono para cada uno de
los taxis disponibles actualmente.
Tras solicitar un servicio, la pantalla de inicio cambia para mostrar la distancia a la que
se encuentra el taxi y la posición del mismo sobre un mapa.
Esta es la pantalla inicial de la aplicación para taxistas. Muestra un formulario para in-
troducir usuario y contraseña. Tras pulsar en “Iniciar sesión” se procede a mostrar el
menú inicial.
Esta pantalla aparece directamente tras iniciar sesión, o bien tras abrir la aplicación si se
ha iniciado sesión previamente. Consta de los siguientes elementos:
En el mapa se visualiza la posición actual del taxi. Esta posición se irá notificando
al sistema en intervalos regulares.
Esta pantalla permite visualizar la reputación actual del taxista, mostrando una media de
todas las valoraciones ası́ como un desglose de las mismas por puntuación.
Esta pantalla aparece tras recibir una notificación del sistema, y permite al taxista aceptar
o rechazar el servicio solicitado. En caso de aceptar, se notificará al cliente y se mos-
trará la pantalla de servicio en curso (descrita a continuación). En caso de rechazar la
solicitud, el sistema asignará el servicio a otro taxista y le notificará para que la acepte o
rechace.
Esta pantalla aparece tras aceptar un servicio. Indica la ubicación del cliente, la distancia
estimada hasta el mismo, e incluye un botón “Cómo llegar” que mostrará una ruta para
llegar a la ubicación del cliente desde la posición actual del taxista.
Las aplicaciones móviles utilizan las facilidades proporcionadas por iOS para la presen-
tación de la información en múltiples idiomas. Para ello, todas las cadenas utilizadas en
las aplicaciones se pueden extraer a ficheros de texto fácilmente modificables para cada
idioma que se desee añadir. Ası́ mismo, en caso de que la interfaz no permita fácilmente
la sustitución de cadenas por las de otros idiomas (por ejemplo, las palabras en alemán
suelen ser más largas y quizás no quepan en el espacio disponible), se puede preparar
52
PFC: Taxi! 11. Implementación
una versión de la interfaz, con posiciones y tamaños distintos, para cada idioma que ası́ lo
requiera. De todas formas, la tendencia es a reducir al máximo la necesidad de hacerlo
ası́, aprovechando las facilidades proporcionadas por la tecnologı́a Auto Layout 1 .
El código fuente se ha desarrollado con el objetivo de ser lo más legible posible, comple-
tando con comentarios en aquellos lugares donde pueda haber alguna confusión.
Ruby on Rails impone un desarrollo usando el patrón Modelo Vista Controlador. De este
modo, la organización de los ficheros ya viene de forma que es obvio en qué carpeta
tiene que ir cada uno. Los controllers irı́an dentro de /app/controllers, los modelos
dentro de /app/models, las vistas dentro de /app/views y ası́ sucesivamente.
1
http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/
adoption.html
tokens controller: se encarga del inicio y cierre de sesión por parte de los taxis-
tas, generando los tokens de autenticación correspondientes que se deben utilizar
para interactuar con taxi controller
2. Al ejecutar la herramienta cucumber, nos indicara que los pasos especificados por
el escenario List available taxis no están definidos. Para ello, hay que crear
un fichero cuyo nombre acabe en steps.rb, y definirlos como con el ejemplo si-
guiente:
3. Al volver a ejecutar la herramienta cucumber, nos indica que la ruta no existe. Por
tanto, hay que añadirla al fichero routes.rb.
Obviamente no es necesario ejecutar la herramienta a cada paso (al añadir la ruta tam-
bién podemos añadir la acción en el controller directamente), pero no está de más ha-
cerlo. La idea es implementar el mı́nimo imprescindible para que el test pase.
Actualmente, la plataforma web cuenta con 29 escenarios, compuestos por 125 pasos,
que definen el comportamiento de la API.
Destacar que los controllers de la API se han creado dentro de la ruta /api/v1/ para, en
el caso de añadir funcionalidad o cambiar algún comportamiento, poder hacerlo en otra
ruta (por ejemplo v2) y ası́ mantener la compatibilidad con las versiones actuales de las
apps cliente.
Los frameworks de Apple para desarrollar en iOS también incitan a usar el patrón Modelo
Vista Controlador. Aun ası́, no es tan estricto como Rails en ese aspecto.
Debido a la interfaz diseñada para cada una de las apps, la implementación varı́a de una
a otra. El código fuente está en el mismo proyecto, pero se han configurado dos targets
para generar las dos apps.
SVProgressHUD - para mostrar los mensajes de progreso, éxito y error de las ope-
raciones.
Los controllers se encuentran en la carpeta Taxi Controllers. Los modelos que utilizan
están dentro de la carpeta Models, y las vistas especı́ficas para la aplicación (el resto son
las genéricas del sistema) están en la carpeta UI Classes.
En la carpeta Network APIse encuentra la interfaz con la API del servidor, en la clase
TaxiAPIClient, y un singleton para la interacción con la API del sistema de localización,
en la clase TaxiLocationDelegate.
La relación entre view controllers, transiciones y las vistas de cada uno se definen en el
fichero TaxiStoryboard. A continuación se muestra una captura de pantalla del conte-
nido de dicho fichero, que define la interacción de la interfaz de usuario de la aplicación
del taxista.
En este caso también se utilizan los mismos modelos y clases de interacción con la
API.
12.1. Cliente
Al pulsar en el con el icono con forma de flecha, se activa el modo de seguimiento del
mapa, lo que hace que se centre en la posición del usuario y se acerque hasta ver
la zona alrededor del usuario con más detalle. Mientras el botón esté activo, el mapa
seguirá automáticamente al usuario, por lo que siempre estará centrado en la posición
del usuario. Además de pulsando sobre el botón de nuevo, también se desactiva este
modo al realizar un desplazamiento en el mapa manualmente.
61
PFC: Taxi! 12. Funcionamiento de la aplicación
Al pulsar en el botón con el texto “Ver taxis”, se muestran en el mapa los taxis disponibles
en ese momento, con un icono para cada uno. El mapa se acerca o aleja automática-
mente de forma que queden visibles todos los taxis, además de la posición del usuario.
Al pulsar sobre uno de los taxis, se muestra su identificador.
Al pulsar en el botón con el texto “Pedir taxis”, se muestra un panel con las opciones para
solicitar un taxi. Permite seleccionar si se desea solicitar el taxi para ahora, o reservarlo
para que la recogida sea dentro de una hora o dos horas. Además, aparece un pin en la
posición del usuario (mostrando el texto “aquı́” y la dirección de dicho punto), que será la
posición que se indique al sistema para la solicitud. Este pin se puede mover haciendo
una pulsación larga sobre el mismo y arrastrándolo a la ubicación deseada. Al pulsar en
el botón “pedir” se confirma la solicitud.
Cuando el taxista asignado al servicio lo acepta, se envı́a una notificación push al usuario
para indicarle este hecho. La notificación se muestra de forma distinta dependiendo de
si la aplicación se encuentra abierta o cerrada en el momento de recibirla.
Figura 12.5: App Cliente: notificación taxi en camino, con la app cerrada y abierta
Figura 12.7: App Cliente: notificación taxi llegando, con la app cerrada y abierta
El servicio solicitado por el usuario pasa del estado “pendiente” a “taxista en camino”
en el momento de la aceptación, y de “taxista en camino” a “trayecto en curso” en el
momento de la recogida.
Figura 12.8: App Cliente: estados de un servicio - pendiente, taxista en camino, iniciado
Cuando el trayecto se completa, el taxista indica la finalización del servicio. En ese mo-
mento se envı́a una notificación push al usuario para indicarle este hecho, y que puede
valorar si ası́ lo desea el servicio recién concluido. La notificación se muestra de forma
distinta dependiendo de si la aplicación se encuentra abierta o cerrada en el momento
de recibirla.
Figura 12.9: App Cliente: notificación finalización servicio, con la app cerrada y abierta
Cuando hay un servicio pendiente de puntuar, se muestra un botón con un icono con
forma de estrella en la parte superior derecha de la pantalla principal. Al pulsar sobre
el mismo, aparece un panel con cinco estrellas, sobre las que se puede pulsar para
establecer la puntuación que se desea dar al servicio. Una vez hecho esto, al pulsar
en el botón “puntuar” se registra esta puntuación en el sistema y el icono de puntuar
desaparece.
12.2. Taxista
Para iniciar la sesión basta con introducir el usuario y la contraseña en los campos indi-
cados. Si alguno de los datos no es correcto, se muestra un mensaje de error.
Desde la pantalla principal se muestra la disponibilidad actual del taxi. Pulsando sobre
los botones “disponible” y “ocupado” se cambia la disponibilidad del taxi en el servidor,
de cara a recibir potenciales asignaciones de servicio. En el mapa se muestra la posición
actual del taxi, que se notificará al servidor a medida que se detecte que ha cambiado.
Si se indica que el taxi no está disponible, se deja de actualizar la posición en el servi-
dor.
Cuando hay una nueva solicitud de servicio y el sistema lo asigna a un taxista, se envı́a
una notificación push al taxista para indicarle este hecho. La notificación se muestra
Figura 12.15: App Taxista: notificación nuevo servicio asignado, con la app cerrada y
abierta
La pantalla de servicio en curso muestra los mismos datos que la de nueva solicitud:
dirección donde se encuentra el cliente, distancia al mismo, y un mapa con la posición
del cliente y el taxi. El botón “cómo llegar” abre la aplicación nativa de mapas de iOS
en modo navegación con una ruta desde la posición actual del taxi hasta la posición del
cliente.
12.2.6. Reputación
Desde la pantalla principal, pulsando en el botón “ver reputación” se muestra una pantalla
con una media de las puntuaciones recibidas, y un desglose del número de valoraciones
recibidas para cada puntuación.
Los riesgos descritos en los primeros capı́tulos han estado muy presentes durante el
desarrollo del proyecto. Las previsiones indicadas en el cronograma se han cumplido,
gracias a haber incluido márgenes de seguridad para eventualidades. De este modo, el
completar algunas tareas en menos tiempo del estimado ha permitido que otras tareas
se pudiesen alargar sin tener que recurrir a disminuir el alcance del proyecto para poder
completarlo dentro del plazo.
75
PFC: Taxi! 13. Conclusiones
Desde el principio me planteé la realización del proyecto como una oportunidad para
explorar áreas que desconocı́a, con ánimo de mejora personal, en lugar de recurrir a lo
conocido o habitual.
Tengo algunos años de experiencia en Ruby on Rails, pero no habı́a utilizado nunca
Cucumber para definir las especificaciones y el comportamiento deseado antes de es-
cribir una lı́nea de código (BDD – Behaviour-Driven Development, Desarrollo Dirigido por
Comportamiento1 ). Los resultados han sido más que satisfactorios y estoy convencido
que seguiré utilizando este paradigma en el futuro.
Ası́ mismo, habı́a desarrollado aplicaciones nativas en iOS con las versiones 3 y 4, pero
nunca habı́a hecho nada con las mejoras tanto en las API como en el lenguaje introduci-
das a partir de iOS 5 como ARC (Automatic Reference Counting)2 o Storyboards3 , que
han resultado reveladoras, pues permiten un desarrollo mucho más rápido y ágil que en
versiones anteriores, escribiendo mucho menos código y menos propenso a bugs.
Entre las posibles mejoras que se podrı́an desarrollar en futuras versiones se pueden
encontrar:
• Utilizar un servidor SSL para que la comunicación con el servidor sea median-
te HTTPS. De este modo la comunicación va encriptada desde el principio.
1
http://en.wikipedia.org/wiki/Behavior-driven development
2
https://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/
Introduction.html
3
https://developer.apple.com/library/ios/documentation/General/Conceptual/Devpedia-CocoaApp/
Storyboard.html
Mejorar el método de cálculo de distancia entre el cliente y el taxista. Dadas las li-
mitaciones de tiempo existentes, la distancia euclı́dea ofrecı́a un compromiso ideal
entre practicidad y tiempo de desarrollo; de hecho, debido a su simplicidad, es muy
buena opción para determinar el taxi a asignar (evitando costosas llamadas a APIs
que devuelvan un resultado más exacto), y en esos casos la diferencia respecto
a la distancia real se puede despreciar. No obstante, no es muy práctica para in-
formar al taxista o al cliente, pues no deja de ser la distancia en lı́nea recta entre
dos puntos, sin tener en cuenta accidentes geográficos ni el trayecto que siguen
las carreteras. En este caso serı́a más práctico de cara a ofrecer una información
más fiable obtener esta distancia mediante una API que proporcione además una
estimación del tiempo de llegada teniendo en cuenta el tráfico o la ruta más óptima.
Versión para iPad. Quizás para la versión del cliente pueda ser superflua, de ahı́ que
no se considerase en un principio, pero a medida que ha transcurrido el desarrollo
he podido observar que la aplicación para el taxista se podrı́a beneficiar del mayor
espacio disponible en una tableta para ofrecer una interfaz aún más optimizada y
práctica, especialmente teniendo en cuenta que se podrı́a utilizar un soporte para
tenerlo visible en la consola central del coche.
14.1. Bibliografı́a
Drance, Matt; Warren, Paul. (2011). iOS Recipes. Estados Unidos: The Pragmatic
Programmers, LLC
Valim, José. (2011). Crafting Rails Applications. Estados Unidos: The Pragmatic
Programmers, LLC
Adamson, Chris; Dudney, Bill. (2012). iOS SDK Development. Estados Unidos: The
Pragmatic Programmers, LLC
Wynne, Matt; Hellesøy, Aslak. (2012). The Cucumber Book. Estados Unidos: The
Pragmatic Programmers, LLC
Dees, Ian; Wynne, Matt; Hellesøy, Aslak. (2013). Cucumber Recipes. Estados Uni-
dos: The Pragmatic Programmers, LLC
Ruby, Sam; Thomas, Dave; Heinemeier Hansson, David. (2013). Agile Web Deve-
lopment with Rails. Estados Unidos: The Pragmatic Programmers, LLC
Thomas, Dave. (2013). Programming Ruby 1.9 & 2.0. Estados Unidos: The Prag-
matic Programmers, LLC
iOS
1
http://stackoverflow.com
2
https://developer.apple.com/videos/
78
PFC: Taxi! 14. Fuentes de información
Ruby on Rails
• Railscasts. http://railscasts.com6
3
http://ideveloper.tv
4
http://cs193p.stanford.edu
5
https://developer.apple.com/library/ios/navigation/
6
http://railscasts.com
7
http://guides.rubyonrails.org