una red social sin prejuicios desarrollada con las últimas ... · aplicación completa, que tenga...
TRANSCRIPT
Peachy: Una red social sin prejuicios desarrollada con las últimas tecnologías multiplataforma Kedi Agbogre Ripa
Desarrollo de Aplicaciones Multiplataforma Curso 17/18 CPIFP Los Enlaces
Proyecto 2º año — 15 de Junio de 2018
Agradecimientos
A D. Óscar Pellejero, tutor y supervisor, por el seguimiento realizado a lo largo de los dos meses de desarrollo de proyecto.
A mis compañeros, familia, y amigos por realizar pruebas con la aplicación,
y compartir sus opiniones y consejos que han servido de manera indispensable en la mejora del proyecto.
A la gran comunidad de desarrolladores de React Native, y Facebook,
por desarrollar con tanta pasión, esfuerzo e ilusión esta nueva tecnología innovadora para simplificar la creación de aplicaciones móviles
multiplataforma.
Página 2
ÍNDICE DE CONTENIDOS
Capítulo 1: Introducción 6 1.1. Contexto 6
Las redes sociales. A dónde vamos y de dónde venimos. 6 1.2. Objetivo y motivación 7
Capítulo 2: Documento de Acuerdo 9 2.1. Requisitos 9
2.1.1. Requisitos funcionales 9 2.1.1.1. Requisitos de cara al cliente 9 2.1.1.2. Requisitos de cara al servidor 10
2.1.1. Requisitos no funcionales 11 2.2. Tareas 11
2.2.1. Tareas de diseño 11 2.2.2. Tareas de implementación 12 2.2.3. Tareas de Pruebas 12
2.3. Metodología 12 2.4. Planificación temporal 13 2.5. Presupuesto 13
2.5.1. Gastos totales del proyecto 14
Capítulo 3: Análisis y diseño 15 3.1. Análisis y diseño de la arquitectura de la aplicación 15
3.1.1 Tecnologías utilizadas 15 3.1.2 Arquitectura de componentes 18
3.1.2.1. Servidor 18 3.1.2.2 Cliente 19
3.1.2.2.1 React: una librería en JavaScript para el desarrollo de interfaces 19 3.1.2.2.2 Estructura del Cliente 21
3.2. Modelado de datos 25 3.2.1 Modelo entidad relación 25 3.2.3 Entrada / Salida de Datos 27
3.2.3.1 API REST 27 3.2.4 Schemas (MongoDB) 31 3.2.5 Seguridad de datos 33
3.3. Análisis y diseño del sistema funcional 34 3.3.1 Diagrama de clases UML (Cliente) 34 3.3.2 Diagrama de clases UML (Servidor) 35 3.3.3 Casos de Uso de la Aplicación (Android / iOS) 36
Página 3
3.4. Análisis y diseño de la interfaz de usuario 42 3.4.1 Vista Previa de la Interfaz 43 3.4.2 Tipos de Navegación 49 3.4.3 Diagrama de Navegación 50 3.4.4 Componentes de interfaz gráfico 51 3.4.5 Colores 53 3.4.6 Tipografía 53
Capítulo 4: Implementación 56 4.1 Estructura de ficheros 56
4.1.1 Cliente 56 4.1.2 Servidor 58
4.2 Descripción de directorios y ficheros 59 4.2.1 Cliente 59 4.2.2 Servidor 65
4.3 Funcionamiento del bloqueo de imagen 67
Capítulo 5: Documento de Cierre 70 5.1 Conclusiones 70 5.2 Proyecciones del futuro 71
5.4.1 Publicidad no intrusiva 71 5.4.2 Funcionalidades extra al componente de Chat 71 5.4.3 Plataforma web atacando el Express API 72 5.4.4 Nueva funcionalidad: Guardar a favoritos 73 5.4.5 Integración contínua con Microsoft Visual Studio App Center 73 5.4.6 Sistema de invitaciones 74 5.4.7 Sistema de progreso más robusto 74
Bibliografía 75
Anexos 76
Anexo I - Manual técnico de instalación 77 Instalación y ejecución del servidor 77
Instalación y configuración de Node.js 77 Instalación y configuración de MongoDB Server 77 Obtención y preparación del código fuente 77
Ejecución del cliente 78 Ejecución de la aplicación con Genymotion 78
Anexo II - Cuaderno de Bitácora 79
Página 4
Página 5
Capítulo 1
Introducción
1.1. Contexto
Las redes sociales. A dónde vamos y de dónde venimos.
En los últimos años, el desarrollo de las redes sociales han sufrido un crecimiento estratosférico, convirtiéndose en parte fundamental y cotidiana de nuestras vidas con más de 3 billones de usuarios activos diarios . Lo habitual es que la mayoría de los internautas cuenten con 1
más de un perfil en estas redes. Aunque el término ‘red social’ pueda parecer algo relativamente nuevo, lo cierto es que, ya
en los años 90 podemos encontrar el origen de los gigantes Facebook o Instagram. Una de las primeras redes sociales, Classmates, por Randy Conrads, fue creado en 1995 con la finalidad de que los usuarios pudieran encontrar a viejos compañeros de colegio, instituto o universidad.
Dos años después nace SixDegrees (cuyo nombre proviene de la teoría de los seis grados de separación ), una red social que permitía crear un perfil social y una lista de amigos, características 2
muy similares al concepto que tenemos actualmente de red social.
La primera revolución de las redes sociales llega en 2003 con la creación de MySpace, una red social que ya permitía desarrollar un perfil completo en internet, con áreas como: información acerca de tí, tus gustos e intereses, y preferencias a la hora de conocer gente, así como la posibilidad de compartir fotos y música. En 2003 también surge LinkedIn, concebida como una red social para profesionales, que en la actualidad cuenta con más de 400 millones de usuarios.
1 Social media - Statistics & Facts. https://www.statista.com/topics/1164/social-networks/ 2 Six Degrees of Separation. Wikipedia. https://en.wikipedia.org/wiki/Six_degrees_of_separation
Página 6
En 2004, en pleno boom del Messenger, aplicación de escritorio de mensajería instantánea por Microsoft, Mark Zuckerberg fundó Facebook, consiguiendo crear un antes y un después en la historia de las redes sociales.
A partir de la aparición de Facebook, éste se consideró la red social estándar. Surgieron más
tarde otras redes sociales (como Tuenti, fundado en España en 2006), pero todas atendían -en su mayor parte- a la estructura de red social dictada por el gigante Facebook.
El concepto de red social online nació de las páginas web, pero, más recientemente, gracias a la aparición de los smartphones y sus aplicaciones, hemos visto un nuevo cambio en las redes sociales. Más bien, hemos visto la adición de una nueva categoría de servicio de red social: los “motores de búsqueda sociales”.
Estamos hablando de redes sociales como Tinder, fundado en 2012, que, mediante algoritmos propios de la aplicación, teniendo en cuenta la localización del usuario, gustos e intereses, y otra información, proporcionan una selección de personas que en un principio son compatibles con el usuario.
Tinder es la aplicación más conocida y de más éxito en esta categoría. Tras calcular la selección de personas compatibles con el usuario, son presentados al usuario como “cartas” con la imagen de la persona, que puedes deslizar hacia la izquierda (si no le interesa), o hacia la derecha (si le interesa).
1.2. Objetivo y motivación
Con este proyecto se desea ofrecer un servicio de red social multiplataforma (Android, iOS, web) para poder encontrar personas con intereses similares sin dar lugar a prejuicios, mediante un sistema de bloqueo de datos del perfil.
La aplicación, mediante un algoritmo interno, encontrará personas compatible con los gustos del usuario. El usuario entonces, podrá acceder al perfil de la persona, pero algunos de los datos estarán bloqueados, por ejemplo, la imagen de perfil, la edad, la localización (no más allá de a nivel de ciudad). Sin embargo, su enfoque principal no será encontrar a personas para relaciones sociales, sino también se extenderá a relaciones profesionales, por ejemplo, para encontrar personas con alguna habilidad concreta para realizar proyectos de cualquier tipo, o incluso para empleo.
Página 7
Por culpa de los prejuicios de imagen, edad, raza, etcétera, pienso que se pierden muchas buenas oportunidades que potencialmente podrían llegar al éxito. Con esta aplicación, se intenta eliminar cualquier tipo de prejuicio posible, animando a ambas personas a conocerse más antes de saltar a conclusiones.
A nivel de aprendizaje personal, mi objetivo con este proyecto también es desarrollar una aplicación completa, que tenga soporte para varias plataformas e idiomas, y que pueda estar publicada en Google Play Store, todo esto utilizando e investigando sobre las últimas tecnologías de desarrollo de aplicaciones multiplataforma.
This project aims to offer a cross-platform (Android, iOS, web) social networking service, for
the user to be able to find people with similar interests without judging, by using a profile data unlocking system.
The program, with its internal algorithm, will find people compatible with the user by comparing each others interests and location. The user will then be able to access the person’s profile, but some of the data will be locked, e.g. the profile picture, age, location (no more than city-level).
Nonetheless, it won’t be focused only on searching compatible people for social relationships - it will also be extended to support business / professional relationships as well, so employers or freelance project leaders can find people with a particular set of skills to work with them.
Due to judgements of physical appearance, age, race, etc. I believe that many good opportunities that could potentially lead to success are lost. With this application, it is sought to prevent any possible judgement, by encouraging our users to get to know each other a bit more by talking about their interests or skills before jumping to conclusions.
At a personal learning level, my aim is also to build a complete application package, an
application that supports multiple platforms, that is internationalized, and could potentially be published to the Google Play Store. All of this, of course, while using the latest and greatest cross-platform app development technologies.
Página 8
Capítulo 2
Documento de Acuerdo
2.1. Requisitos
2.1.1. Requisitos funcionales
Los requisitos funcionales de la aplicación se dividen en tres partes, requisitos de cara al cliente y requisitos de cara a la gestión interna o de servidor.
2.1.1.1. Requisitos de cara al cliente
● RFC 1. La aplicación debe tener una sistema de inicio sesión mediante redes sociales ya existentes, como Facebook, Twitter, Google+. Esta pantalla se mostrará al entrar en la aplicación si no hay una sesión abierta y activa.
● RFC 2. La aplicación debe tener un sistema de recuperación de cuentas mediante correo electrónico. Este mismo sistema de correos electrónicos se utilizará también para enviar correos desde la aplicación (cuando un usuario se registra, por ejemplo).
● RFC 3. La aplicación deberá tener una barra de búsqueda en la parte superior en todas las pantallas (menos la de carga), que permita al usuario comenzar una búsqueda de publicaciones por intereses o habilidades, y tags.
● RFC 4. La aplicación deberá incluir un menú de navegación lateral izquierdo (Drawer), con la imagen del usuario, el nombre, y el correo electrónico. Debajo de la información, se añadirán los siguientes enlaces: Ajustes de Cuenta, Sobre la Aplicación, y un botón de Cerrar sesión.
● RFC 5. La aplicación deberá incluir un menú de navegación inferior basado en “Tabs”, con tres enlaces: Explorar (Principal), Nuevo Post, y Chat (en el que aparecerá un indicador de mensajes no leídos). Estos enlaces deberán incluir iconos representativos.
● RFC 6. La pantalla principal de la aplicación deberá ser la pantalla de “Explorar”, en la que aparecerán resultados automáticos previamente procesados sin que el usuario tenga que realizar ninguna búsqueda.
Página 9
● RFC 7. La pantalla de chats recientes (accesible desde el menú inferior) deberá mostrar todos los chats recientes, ordenados por última intervención.
● RFC 8. La pantalla de chat individual deberá mostrar todos los mensajes previamente enviados junto con su fecha y hora de envío. También deberá poder enviar y recibir mensajes en tiempo real. Además, aparecerá la imagen y nombre de la persona en la parte superior de la ventana, pudiendo estar bloqueada si aún no ha sido desbloqueada.
● RFC 10. En todos los lugares donde aparezca el nombre de la persona, se podrá hacer clic para que lleve al perfil de dicha persona. En la pantalla de perfil, aparecerá los datos bloqueados y desbloqueados de la persona en cuestión. Para poder desbloquear más información, se anima al usuario a que inicie una conversación con dicha persona.
● RFC 11. En todos los lugares de la aplicación donde aparezcan imágenes de usuarios, éstas deberán aparecer difuminadas o no dependiendo del estado de relación (calculado a partir del número de mensajes entre los dos usuarios). Recordamos que ésta información sensible se desbloquea mediante la conversación en chat, que irá sumando puntos a medida que la conversación avance.
● RFC 12. Al iniciar una búsqueda rápida desde el buscador de la parte superior de la aplicación, se desplegará una lista de sugerencias dividida en perfiles y posts. Al introducir un término a buscar se realizará una búsqueda para ambos.
● RFC 13. La pantalla de resultados de búsqueda mostrará personas con el formato de “Carta”, con la imagen de la persona bloqueada, mostrando algunos datos, como la lista completa de intereses de dicha persona.
● RFC 14. En la pantalla de perfil (accesible desde el menú inferior, RF 5), el usuario debe poder cambiar su imagen, datos personales, intereses, y habilidades.
● RFC 15. En la pantalla de Ajustes de Cuenta, accesible desde el menú Drawer, el usuario deberá poder cambiar el correo electrónico, nombre de usuario, contraseña (o añadir una), y editar opciones de privacidad.
2.1.1.2. Requisitos de cara al servidor
● RFS 1. El servidor permitirá la autenticación de usuarios mediante email/contraseña o mediante otras redes sociales (Facebook, Twitter, Instagram, Google+).
Página 10
● RFS 2. El servidor tendrá un API REST en el que se expondrán los siguientes recursos a usuarios autenticados: publicaciones (posts), lista de chats, mensajes de un chat individual, información de perfiles.
2.1.1. Requisitos no funcionales
● RNF 1. La aplicación debe soportar internacionalización. Y debe incluir los idiomas español e inglés por defecto.
● RNF 2. Toda comunicación realizada desde y hacia la aplicación debe estar cifrada.
● RNF 3. La aplicación debe soportar, al menos, las plataformas Android e iOS.
● RNF 4. Las contraseñas de los usuarios deben estar protegidos mediante una función criptográfica de hash.
● RNF 5. Los datos guardados en base de datos deben ser respaldados diariamente en un servidor remoto.
2.2. Tareas
Las tareas a realizar se clasifican en: Diseño, Implementación y Pruebas.
2.2.1. Tareas de diseño
❏ Diseño de interfaz (43h):
❏ Pantalla de inicio de sesión / registro / recuperación. 3h ❏ Pantalla “Explorar”. 8h ❏ Pantalla “Chats”. 8h ❏ Pantalla individual de chat. 8h ❏ Pantalla de perfil. 3h ❏ Pantalla de ajustes de cuenta. 3h ❏ Pantalla de resultados de búsqueda. 6h ❏ Pantalla de “Sobre la aplicación”. 2h ❏ Menús (Drawer y Tabs). 2h
● Diseño de BBDD. Entidades y relaciones, modelo relacional. (10h)
Página 11
● Diseño de API REST. Determinar las endpoints, y datos de entrada y salida de cada una. (10h)
2.2.2. Tareas de implementación
❏ Desarrollo (77h):
❏ Sistema de sesiones, recuperación de cuenta. 10h ❏ Sistema de búsqueda. 15h ❏ Sistema de perfiles. 6h ❏ Sistema de chat en tiempo real. 20h ❏ Sistema de notificaciones push. 15h ❏ Sistema de correos electrónicos SMTP. 4h ❏ Sistema multilenguaje. 5h ❏ Implementación de AdMob. 2h
● Servicios externos (16h):
❏ Configurar servicio de correo electrónico (Mailgun). 5h ❏ Configurar Google Analytics. 5h ❏ Configurar Google AdMob. 5h ❏ Notificaciones Push. 1h
2.2.3. Tareas de Pruebas
❏ Generación de pruebas unitarias. 10h ❏ Validación de pruebas. 10h
2.3. Metodología
La metodología que se utilizará en el desarrollo de este proyecto será ágil e iterativa, mediante sprints. Se realizarán reuniones con el equipo cada dos semanas aproximadamente, siendo los días en cuestión:
❏ 16/04/2018 ❏ 07/05/2018 ❏ 21/05/2018 ❏ 04/06/2018
Página 12
2.4. Planificación temporal Cada día se realizará una sesión de desarrollo de un total de 4 horas. Tras visualizar todas las tareas valoradas en el apartado 2.2, se realizarán en distintas fases:
1. Fase de diseño - abarca desde el 15 de abril hasta el 1 de mayo.
➔ Esta fase se enfocará a diseño, pero se realizarán las implementaciones más sencillas a medida que se diseñan las interfaces para ellas.
2. Fase de implementación - desde el 1 de mayo hasta el 29 de mayo. 3. Fase de pruebas - desde el 29 de mayo hasta el 8 de junio.
2.5. Presupuesto
En este apartado del documento se detallan los costes del proyecto en caso de que se quisiera llevar a una aplicación comercial.
Tipo de coste Concepto Gasto
Costes iniciales Licencia Google Play Android 25 €
Costes fijos Servidor Ubuntu Server 16.04 14 € / mes
Dominio Web (peachyapp.co) 20 € / año
Sueldo (Analista Programador) 12 € / hora
Figura 1. Tabla de costes
❏ Costes iniciales. Los costes iniciales del proyecto estarían constituidos únicamente por la licencia de desarrollo Google Play (25 €), de pago único, para poder la aplicación en la tienda de aplicaciones.
❏ Costes fijos. En los costes fijos se encuentran: el pago mensual del servidor Linux (14 €) en el que se encuentra el servidor de la aplicación y el posible servidor web, y el dominio (20 €) peachyapp.co.
Los gastos son bastante reducidos, puesto que ni las tecnologías o las herramientas de desarrollo utilizadas requieren de pagos, puesto que son Open Source.
Página 13
Se ha intentado también encontrar un servidor que minimizara los costes de hosting, y al final se ha optado por un servidor en Contabo.com, en concreto un servidor virtual (VPS) Ubuntu Server 16.04 de categoría L. El servidor tiene las siguientes prestaciones por 14 € / mes:
❏ Núcleos de CPU: 4 (compartidos) ❏ Tamaño de disco: 300GB SSD ❏ RAM: 12GB (garantizada) ❏ Sistema Operativo: Ubuntu Server 16.04
Con estas características se espera poder servir varios miles de clientes antes de tener que escalar a más servidores por posibles problemas de rendimiento.
2.5.1. Gastos totales del proyecto
El desarrollo del proyecto ha durado un total de 53 días con 5 horas dedicados cada día. El gasto total del proyecto en este periodo ha sido:
Concepto Coste
Coste Hardware 28 €
Coste Software 45 €
Coste Recursos Humanos 53 * 5 = 265h * 12€/h = 3975 €
TOTAL 4048 €
FIGURA 2. Tabla de gastos totales
Página 14
Capítulo 3
Análisis y diseño 3.1. Análisis y diseño de la arquitectura de la aplicación
3.1.1 Tecnologías utilizadas
El lenguaje principal utilizado para el desarrollo del proyecto será JavaScript
En cuanto al cliente, el framework elegido para desarrollo de aplicaciones multiplataforma
(iOS, Android) React Native : 3
React Native es un framework desarrollado por Facebook y lanzado al público en 2015. Con React Native, es posible programar con un mismo código JavaScript para iOS y Android, con cambios mínimos para cada plataforma.
Esto es deseable puesto que el tiempo de desarrollo del proyecto es limitado a dos meses (abril y mayo). Con React Native, pues, será posible crear una aplicación técnicamente nativa, con soporte a Android e iOS sin ser necesario programar separadamente para cada plataforma (Java para Android, Objective C / Swift para iOS).
Esta tecnología ya está siendo utilizada por grandes empresas en sus aplicaciones con más de 100 millones de usuarios diarios. Por nombrar algunas de ellas, destacan:
● Instagram (Facebook). Aplicación móvil red social. 800 millones de usuarios. 4
● Airbnb. Aplicación móvil de hostelería. 150 millones de usuarios. 5
● Skype (Microsoft). Aplicación móvil de mensajería instantánea. 300 millones de 6
usuarios. ● Walmart. Aplicación móvil de una de las cadenas de supermercados más grandes del
mundo.
3 https://facebook.github.io/react-native/ React Native. 4 https://www.statista.com/statistics/253577/number-of-month... Instagram Monthly Active Users 2017. 5 https://expandedramblings.com/index.php/airbnb-statistics/ 100 Amazing Airbnb Statistics and Facts. 6 https://expandedramblings.com/... How Many Users do Skype and Other Top Chat Apps Have?
Página 15
Como se puede observar, React Native es un framework utilizado por los grandes, y ha demostrado que una aplicación realizada con él puede tener buen rendimiento y soportar un gran volumen de usuarios.
Otra ventaja es que React Native incorpora la arquitectura dictada por React , el framework 7
de desarrollo de aplicaciones web más utilizado hoy, por grandes aplicaciones como las aplicaciones web de Facebook, Spotify, Outlook, Netflix, etc. Esto hace su implementación web trivial puesto que existen muchas similitudes entre ambas, y además, muchos de los componentes son reutilizables, 8
favoreciendo la reusabilidad de código.
React Native es compatible con Android 4.1+ y iOS 8+. Esto abarca el 99.94% de dispositivos iOS y el 99.3% de dispositivos Android en la actualidad. Es decir, es prácticamente compatible con todos los dispositivos Android e iOS actuales, lo cual es otra ventaja porque nos garantiza todo el mercado de dispositivos móviles como usuarios potenciales.
El API y el servidor WebSocket son desarrollados con Node.js. El API utiliza el paquete Express.js para controlar todas las peticiones del cliente, y el servidor WebSocket funciona con 9
el paquete ws (WebSocket) . 10
El SGBD utilizado es MongoDB, no relacional, la cual tiene una muy buena integración con
entornos JavaScript como Node.js mediante el driver oficial . La autenticación se realiza mediante 11
un sistema de JWT (JSON Web Tokens ). 12
El token tiene codificados los siguientes datos en formato JSON:
Nombre de campo Descripción
_id Id de objeto de MongoDB.
email Email de usuario.
guid Valor único de usuario.
exp Timestamp de expiración.
ip IP de usuario.
7 https://reactjs.org/ ReactJS. 8 https://reactjs.org/docs/react-component.html Componentes de React. 9 https://expressjs.com/ Express.js. 10 https://github.com/websockets/ws ws for Node.js. 11 http://mongodb.github.io/node-mongodb-native/ MongoDB para Node.js. 12 https://jwt.io/introduction/ JSON Web Tokens.
Página 16
Figura 3. Contenido del JWT
Nota Los JWT van firmados pero no cifrados. Con la clave secreta del servidor podemos comprobar que los datos del token no han cambiado, de modo que podemos realizar la autenticación de manera sencilla en el servidor.
En cuanto a los programas y herramientas utilizadas para el desarrollo, son los siguientes:
● Visual Studio Code para programación de cliente (React Native) y servidor (Node.js). 13
● Robomongo Studio 3T para visualización / edición de datos de base de datos 14
MongoDB. ● Android Studio 3.1.1 para la compilación de la aplicación Android. 15
● Máquina Virtual de Mac OS X 13 (High Sierra) con Xcode, para la compilación de la aplicación para iOS.
Figura 4. Tecnologías utilizadas
13 https://code.visualstudio.com/ Visual Studio Code. 14 https://robomongo.org/ Robomongo Studio 3T. 15 https://developer.android.com/studio/index.html Android Studio.
Página 17
3.1.2 Arquitectura de componentes
Los componentes utilizados en la aplicación son los siguientes:
3.1.2.1. Servidor
Dividido en dos componentes fundamentales, ambos escuchando en el mismo puerto (por defecto 3114).
● Servidor WebSocket . Permite la comunicación no solicitada de servidor a cliente 16
(principalmente para la funcionalidad de chat). Tiene los siguientes eventos:
○ peachy.Authenticate: Enviado por el cliente cuando desea autenticar su websocket con un JWT.
○ peachy.SendMessage: Enviado por el cliente cuando desea enviar un mensaje a otro usuario.
● REST API. Trata las peticiones HTTP. Permite el acceso a recursos de forma controlada y permite también desencadenar respuestas de los sockets hacia el cliente. El API tiene los siguientes endpoints:
Ruta Descripción y funcionamiento
/api/token Obtención de JWT firmado para la autenticación de usuario. También autentifica el socket del usuario.
/api/logout* Invalida todos los JWT del usuario, forzando el cierre de sesión.
/api/profile/<id>/info* Obtiene información de perfil pública de un usuario determinado por el parámetro id.
/api/profile/<id>/pic* Devuelve la imagen de perfil del usuario.
/api/profile/location* Recibe latitud y longitud del usuario, realiza y devuelve la geocodificación inversa, y guarda los datos de localización obtenidos.
/api/signup Realiza la creación de un usuario.
/api/posts* Devuelve publicaciones compatibles con el usuario.
/api/posts/create* Ruta para publicar un post.
/api/search* Devuelve los resultados de una búsqueda.
16 https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API Protocolo WebSockets.
Página 18
/api/chat/list* Devuelve la lista de chats relevantes al usuario.
/api/chat/<id>/messages* Devuelve la lista de mensajes de un chat determinado.
(*) Requieren autenticación para ser accedidos.
Figura 5. API Endpoints
Como componente de servidor externo, se incluye también el servidor de FCM (Firebase Cloud Messaging ), que es el encargado de enviar las notificaciones push bajo las órdenes del 17
servidor principal de la aplicación.
3.1.2.2 Cliente
3.1.2.2.1 React: una librería en JavaScript para el desarrollo de interfaces 18
Para poder comprender mejor cómo funciona el cliente de la aplicación, es necesario conocer React, puesto que es la tecnología central del proyecto.
React es una librería JavaScript para la creación de interfaces, creada inicialmente por Jordan
Walke, un ingeniero de software de Facebook, y actualmente en desarrollo y manutención por la compañía y la comunidad de desarrolladores individuales que quieren aportar al proyecto Open Source.
Puede ser utilizado para la creación de interfaces web de una sola página (SPA, Single Page Applications) o interfaces nativas para plataformas móviles con React Native (iOS, Android, TV).
El objetivo de React no es ser un framework al completo (al contrario de Angular). Se ciñe únicamente a la creación de interfaces. Esto quiere decir que los desarrolladores deberán buscarse la vida creándose sus propias librerías para funcionalidades tales como peticiones HTTP, websockets, guardado de datos local… Sin embargo, React posee algunas características para aligerar el desarrollo y hacer las aplicaciones más eficientes.
La característica más notable de React es el uso de un “DOM Virtual”: La librería crea en memoria la estructura de datos de la interfaz, una abstracción, a partir de la cual calcula las diferencias y actualiza la interfaz de una manera eficiente.
17 https://firebase.google.com/docs/cloud-messaging/ FCM (Firebase Cloud Messaging). 18 https://en.wikipedia.org/wiki/React_(JavaScript_library). React en Wikipedia.
Página 19
Para definir interfaces en React, se puede utilizar (aunque no es obligatorio) la sintaxis de
JSX (JavaScript XML), una extensión del lenguaje JavaScript. Mediante JSX, React quiere hacer el desarrollo de interfaces más sencillo e intuitivo para los desarrolladores.
Ejemplo de sintaxis:
class App extends React.Component { render() {
return ( <View> <Text>Hello World</Text> </View> );
}
}
Figura 6. Código Hello World en React
La llegada de React Native en 2015
React, en sus comienzos, estaba disponible únicamente para interfaces web. En 2012, Mark Zuckerberg comentó: “La equivocación más grande que hicimos como empresa fue apostar demasiado en HTML5 en lugar de tecnologías nativas ”. Prometió que Facebook proporcionaría 19
una experiencia móvil mucho mejor.
Dentro de Facebook, Jordan Walke encontró una manera de generar una interfaz móvil para iOS mediante un hilo JavaScript ejecutándose en segundo plano. Facebook decidió organizar un Hackathon para perfeccionar este prototipo para poder crear aplicaciones móviles nativas mediante esta nueva tecnología.
Fue en el React.js Conf 2015 donde se reveló la primera versión de React Native, corrigiendo por fin el error que Mark Zuckerberg comentó en 2012: React Native no utiliza HTML5, todo está programado en JavaScript, y depende de SDKs nativas a cada plataforma.
¿Cómo funciona React Native?
En React Native, contrario a ReactJS para web que utilizaba el DOM para renderizar los componentes, se utilizan vistas nativas a cada plataforma para renderizarlos. Esto es posible
19 https://mashable.com/2012/09/11/html5-biggest-mistake El gran error de Zuck.
Página 20
mediante un “conector” o “puente” (bridge) a través del cual se comunica el markup interpretado (JSX) que genera las funciones render de los componentes en React Native, traduciéndose en elementos nativos.
Figura 7. Funcionamiento de React
Cada componente en React tiene su propio estado, un objeto en JavaScript. Como indica el nombre de la biblioteca, React “reacciona” a los cambios de valor en el estado, y re-renderiza los componentes de acuerdo a estos cambios. Esto es muy eficiente, puesto que sólo se renderizan los componentes que realmente cambian, en lugar de toda la vista.
3.1.2.2.2 Estructura del Cliente
Responde a un paradigma de programación reactivo utilizando React de Facebook para la interfaz 20
y MobX para la gestión de estados de la aplicación. Se divide principalmente en: 21
❏ Componentes de interfaz gráfico, que son distintos componentes que se utilizan para representar cada una de las pantallas de la aplicación y cada unidad de elemento de interfaz. Por ejemplo, la pantalla de inicio de sesión es un componente, pero un campo de texto contenido en él también lo es. Representan la información obtenida de los Stores y almacenada en los servicios.
❏ Stores, en los que se encuentran los métodos de obtención de datos del exterior, ya sea del API, del servidor de websockets, etc., y también donde estos datos son almacenados para su posterior consumición por los componentes del interfaz gráfico.
20 https://en.wikipedia.org/wiki/Reactive_programming Programación reactiva. 21 https://github.com/mobxjs/mobx Gestor de estados de aplicación MobX.
Página 21
La aplicación de cliente tiene los siguientes Stores:
❏ Autenticación. Se encarga de realizar la autenticación del cliente actual, realizando una petición al REST API para obtener un JWT firmado.
❏ Internacionalización. Incluye métodos de obtención del lenguaje del usuario y maneja el uso de distintos ficheros de traducción.
❏ Geolocalización. Obtiene la localización del usuario mediante internet o GPS para después ser enviada al servidor.
❏ RTC (Real-Time Communication). Se encarga de obtener todos los datos que se representarán en el UI, además de recibir actualizaciones mediante sockets. Por ejemplo: lista de chats, mensajes en un chat individual, notificaciones, publicaciones.
Ejemplo de secuencia de autenticación:
Figura 8. Secuencia de Autenticación
1. El usuario abre la aplicación e inmediatamente se abre una conexión con el servidor WebSocket, la cual devolverá un identificador único (webSocketUniqueId) para poder identificar el cliente con el socket.
2. El usuario inicia sesión desde la aplicación. El cliente REST envía una petición al servidor REST para obtener un JWT sin fecha de expiración.
3. El servidor REST autentifica el socket del cliente con el JWT generado, y devuelve una respuesta al cliente REST con el mismo.
4. Ahora el cliente puede recibir mensajes del servidor mediante socket, y puede acceder a los recursos protegidos del servidor REST.
5. El cliente almacena el token de forma persistente para posteriores peticiones.
Página 22
Nota Para que el servidor pueda autenticar el socket correspondiente, es necesario incluir el valor webSocketUniqueId (el que recibe tras la primera conexión) en la llamada a /api/token. Si no se incluye, únicamente generará y devolverá un JWT. Esto permite que el API pueda ser utilizado sin websockets.
Ejemplo de secuencia de acceso a recursos protegidos (obtener publicaciones):
Figura 9. Secuencia de acceso a recursos protegidos
1. Mediante un cliente ya autenticado (en posesión de un JWT firmado válido), se realiza una petición HTTP al servidor REST. Es necesario incluir la cabecera Authorization: Bearer, especificando en ella el token en cuestión.
2. El servidor REST obtiene los datos de las publicaciones de la base de datos Mongo y los devuelve en formato JSON.
Página 23
Ejemplo de secuencia de funcionalidad en tiempo real (envío de mensaje):
Figura 10. Secuencia de funcionalidad en tiempo real
1. El cliente socket envía una petición (peachy.SendChatMessage) al servidor socket con los datos del mensaje.
2. El servidor socket introduce un nuevo mensaje en la colección de MongoDB. 3. El servidor socket notifica al usuario receptor de dos formas:
a. Mediante socket: Para notificar al usuario dentro de la aplicación, modificando el contador de mensajes, actualizando la lista de mensajes, etc.
b. Mediante FCM (Firebase Cloud Messaging): Para notificar al usuario mediante notificaciones Push, en el caso de que el usuario no esté conectado a la aplicación.
4. El usuario receptor recibe la notificación por socket (si está conectado) y por push (remotamente mediante FCM).
Página 24
3.2. Modelado de datos
3.2.1 Modelo entidad relación
Figura 11. Diagrama Entidad Relación
Página 25
user Usuarios de la aplicación. ❏ _id. Número identificativo generado por MongoDB. ❏ date. Fecha de creación del usuario. ❏ device_token. Código generado por FCM. Identifica el dispositivo del usuario, al que
después será posible enviar notificaciones push. ❏ image. Enlace a la imagen del usuario. ❏ password. Contraseña hasheada (bcrypt). ❏ guid. Identificador único que se utilizará en el JWT. Al cambiar este campo se invalidará
todos los JWT emitidos para este usuario. ❏ email. Correo electrónico.
message Mensajes enviados entre usuarios. ❏ _id. Número identificativo generado por MongoDB. ❏ body. Cuerpo del mensaje. ❏ recipient_id. ID de usuario del receptor. ❏ read. Indica si el usuario receptor ha leído o no el mensaje. ❏ date. Fecha de emisión.
post Publicaciones de usuarios. ❏ _id. Número identificativo generado por MongoDB. ❏ date. Fecha de publicación. ❏ headline. Título del post. ❏ body. Cuerpo del post. ❏ topics. Categorías.
profile Perfil con información extra del usuario.
❏ _id. Número identificativo generado por MongoDB. ❏ interests. Vector de intereses del usuario. ❏ skills. Vector de habilidades del usuario. ❏ image. Imagen de perfil del usuario. ❏ name.
❏ first_name. Nombre del usuario. ❏ last_name. Apellido del usuario.
❏ location. Localización del usuario. ❏ latitude. ❏ longitude. ❏ timezone. Zona horaria de la localización del usuario. ❏ city. Ciudad.
Página 26
3.2.3 Entrada / Salida de Datos
A continuación se detallan los conjuntos de datos de entrada y salida de la aplicación.
3.2.3.1 API REST
POST /api/token
Request Response
(string) email Correo electrónico del usuario
(string) token JWT generado para el usuario
(string) deviceToken Token del dispositivo del usuario (para notificaciones push)
(int) exp Fecha de expiración del token
(string) password
Contraseña del usuario
(JSON Object) payload Contenido del token (_id: string, email: string, guid: string, exp: int, ip: string)
Figura 12. Descripción de ruta de login
GET /api/logout
Request Response
(string) Bearer token Token activo del usuario
(string) code Código de respuesta (ok)
Figura 13. Descripción de ruta de logout
GET /api/profile/<id>/info
Request Response
(string) Bearer token Token activo del usuario
(JSON Object) Objeto que contiene la información de perfil del usuario
Figura 14. Descripción de ruta de información de perfil
Página 27
POST /api/profile/location
Request Response
(string) Bearer token Token activo del usuario
(string) city La ciudad del usuario
(float) latitude Latitud del usuario (string) countryCode El código de país del usuario
(float) longitude Longitud del usuario (string) timezone La zona horaria del usuario
(string) latitude La latitud del usuario
(string) longitude La longitud del usuario
Figura 15. Descripción de ruta de geolocalización
GET /api/profile/<id>/pic
Request Response
(string) <id> ID del usuario (Blob) Imagen redimensionada y difuminada
Figura 16. Descripción de ruta de imagen de perfil
POST /api/signup
Request Response
(string) email Correo electrónico del usuario
(JSON Object) user Datos de interés del usuario (_id: string, guid: string, email: string, date: int)
(string) deviceToken Token del dispositivo del usuario (para notificaciones push)
(string) token JWT generado para el usuario
(string) password Contraseña (int) exp Fecha de expiración
Figura 17. Descripción de ruta de registro
Página 28
GET /api/posts
Request Response
(string) Bearer token Token activo del usuario
(JSON Array) Array con los posts.
(JSON Object) filters? Campo opcional para filtrar los posts. Se puede especificar filters.offset para cargarlos con un offset.
Figura 18. Descripción de ruta de búsqueda
POST /api/posts/create
Request Response
(string) Bearer token Token activo del usuario
(JSON Object) La publicación creada.
(string) headline Título de la publicación
(string) body Cuerpo de la publicación
(JSON Array) tags Etiquetas de la publicación
(bool) restrictedLocation
Indica si la publicación está restringida a la localización del usuario (si está disponible)
Figura 19. Descripción de ruta de publicar
Página 29
POST /api/search
Request Response
(string) Bearer token Token activo del usuario
(JSON Array) Colección de publicaciones/usuarios que pasan el filtro proporcionado (JSON Object) filters Filtros para la
búsqueda
Figura 20. Descripción de ruta de buscar
GET /api/chat/list
Request Response
(string) Bearer token Token activo del usuario
(JSON Array) incoming
(JSON Array) active
Dos colecciones de mensajes, una para los entrantes y otra para los activos.
Figura 21. Descripción de ruta de obtener lista de chat
GET /api/chat/<id>/messages
Request Response
(string) Bearer token Token activo del usuario
(JSON Array) Mensajes del chat JSON Object(_id, userId, body, date)
(string) <id> ID de un usuario participante de un chat
Figura 22. Descripción de ruta de obtener mensajes de chat
Página 30
3.2.4 Schemas (MongoDB)
A continuación se incluyen los Schemas de todas las entidades de la aplicación en JavaScript Object Notation (JSON).
Schema de Mensaje (Message.js)
{
senderId: { type: mongoose.Schema.Types.ObjectId,
ref: "User" },
recipientId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
body: String, read: { type: Boolean, default: false
}
}
Figura 23. Schema de Mensaje
Schema de Usuario (User.js)
{
email: String, password: String, // bcrypted password guid: String, // sent in JWT payload to allow invalidation on demand deviceToken: String // for push notifications }
Figura 24. Schema de Usuario
Página 31
Schema de Perfil (Profile.js)
{
interests: Array, skills: Array, image: Buffer, // binary image birthdate: Date, gender: String, hasDoneIntro: { type: Boolean, default: false }, headline: { type: String, default: "New Peachy user!" }, name: { firstName: String, nickName: String }, location: { city: String, country: String, latitude: String, longitude: String, timezone: String }, userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" } }
Figura 25. Schema de Perfil
Página 32
Schema de Publicación (Post.js)
{ userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" }, restrictedLocation: Boolean, headline: String, body: String, topics: [], tags: [] }
Figura 26. Schema de Publicación
3.2.5 Seguridad de datos
Es esencial en una aplicación enfocada a los datos que proporciona el usuario (puesto que la aplicación trata de una red social), tener los datos almacenados de una forma segura, que impida el acceso a personas no autorizados. Se han tenido en cuenta las siguientes medidas de seguridad:
● Conexión a la base de datos únicamente posible de forma local en el servidor. De esta manera, será únicamente el propio servidor de aplicación el que podrá acceder a la base de datos, sin poder ser accedida remotamente.
● Hasheado de datos importantes. Las contraseñas de los usuarios son almacenados tras pasar por una función hash (BCRYPT ), para evitar cualquier posibilidad de ataque de 22
dispositivos actuales.
● Imposibilidad de inyección en base de datos . Al utilizar MongoDB como el 23
sistema gestor de base de datos, las consultas son representadas como objetos BSON . La 24
librería adaptadora utilizada en el servidor se encarga de construir estos objetos de una forma que impide cualquier tipo de inyección No-SQL.
22 https://en.wikipedia.org/wiki/Bcrypt bcrypt 23 https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-injection FAQ: MongoDB Fundamentals 24 https://en.wikipedia.org/wiki/BSON BSON
Página 33
3.3. Análisis y diseño del sistema funcional
3.3.1 Diagrama de clases UML (Cliente)
Figura 27. Diagrama de clases Cliente
Ver en tamaño completo: https://peachyapp.co/uml/client.svg La aplicación de cliente está construida siguiendo la arquitectura propia de React. Está compuesta por componentes (React.Component), los que se dividen en dos tipos:
● Contenedores (Containers). Son los componentes que representan cada una de las pantallas de la aplicación. Son capaces de obtener información de los Stores, pasarla a componentes hijos, y navegar a otras pantallas. Son componentes como la pantalla de inicio, la pantalla de perfil, etc.
● Componentes sencillos. Son los componentes independientes y reutilizables que se utilizan en los Containers. No tienen conocimiento de la existencia de los Stores, puesto
Página 34
que todos los datos que necesitan se pasan mediante props desde los Containers. Son componentes como los botones, elementos de lista, etc.
Aparte de los componentes, existen los Stores, que son pasados a los Containers mediante props. Los Stores se encargan de obtener y almacenar en memoria la información contenida en el API. Los componentes se actualizarán acorde a la información contenida en ellos.
3.3.2 Diagrama de clases UML (Servidor)
Figura 28. Diagrama de clases Servidor
Ver en tamaño completo: https://peachyapp.co/uml/server.svg
Página 35
3.3.3 Casos de Uso de la Aplicación (Android / iOS)
CU-01
Precondición El usuario no debe estar previamente registrado
Descripción Darse de alta en la aplicación
Actor Usuario de la aplicación
Secuencia Normal Paso Acción
1 Los futuros usuarios deberán iniciar la aplicación en su dispositivo Android o iOS.
2 Una vez en la pantalla de inicio, deberán pulsar en el enlace en la parte inferior de la pantalla “¿Eres nuevo aquí?”.
3 A continuación, se sigue el asistente que orienta al usuario para crear su cuenta y datos iniciales de perfil.
4
Se deberán introducir los datos de perfil iniciales (imagen, nombre, apodo, fecha de nacimiento y sexo), y hacer clic en el botón “Continuar”, que llevará a la pantalla principal de la aplicación.
Figura 29. CU-01
CU-02
Precondición ● El usuario no debe tener una sesión activa ● El usuario debe haberse registrado previamente
Descripción Iniciar sesión en la aplicación para poder acceder a las pantallas interiores de la aplicación
Actor Usuario de la aplicación que se haya registrado previamente
Secuencia Normal Paso Acción
1 Los futuros usuarios deberán iniciar la aplicación en su dispositivo Android o iOS.
2 Una vez en la pantalla principal, deberán introducir sus datos (email y contraseña) en los campos de texto.
Página 36
3 A continuación, se pulsa el botón “Iniciar sesión” para poder acceder al interior de la aplicación.
Figura 30. CU-02
CU-03
Precondición El usuario debe haber iniciado sesión previamente
Descripción Actualizar la imagen de perfil
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá abrir el menú lateral izquierdo
2 El usuario deberá pulsar en la imagen que aparece en la parte superior de la barra lateral
3 El usuario deberá elegir una nueva imagen en el selector de fotos que se inicia
Figura 31. CU-03
CU-04
Precondición El usuario debe haber iniciado sesión previamente
Descripción Actualizar datos del perfil
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá abrir el menú lateral izquierdo
2 El usuario deberá pulsar en el enlace “Ajustes” del menú lateral izquierdo
3 El usuario deberá pulsar en la pestaña de “Perfil”,
4 El usuario deberá modificar uno o más campos del formulario
5 El usuario deberá pulsar en el botón “Guardar”
Página 37
Figura 32. CU-04
CU-05
Precondición El usuario debe haber iniciado sesión previamente
Descripción Realizar una publicación
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1
El usuario deberá navegar a la pantalla de creación de publicaciones (segunda pestaña en la barra inferior)
2 El usuario deberá elegir una o más categorías, pulsando en uno o más iconos de la lista
3 El usuario deberá marcar o no el checkbox para restringir la publicación solo a la localización del usuario
4 El usuario deberá pulsar el botón “Continuar”
5 El usuario deberá rellenar el formulario y pulsar el botón “Publicar”
Figura 33. CU-05
CU-06
Precondición El usuario debe haber iniciado sesión previamente
Descripción Visualizar publicaciones
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá navegar a la pantalla principal de la aplicación (primera pestaña en la barra inferior)
2 El usuario verá las publicaciones relevantes en el carrusel
3 El usuario podrá deslizar a la última publicación y se cargarán más publicaciones dinámicamente
Página 38
Figura 34. CU-06
CU-07
Precondición El usuario debe haber iniciado sesión previamente
Descripción Iniciar un chat con otro usuario
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá navegar a la pantalla principal de la aplicación (primera pestaña en la barra inferior)
2
El usuario deberá ver el detalle de una publicación en concreto y darle a botón “Chatear con …” para abrir una pantalla de chat con el autor de la publicación
Figura 35. CU-07
CU-08
Precondición El usuario debe haber iniciado sesión previamente
Descripción Enviar un mensaje a otro usuario
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá navegar a la pantalla de Chats (tercera pestaña de la barra inferior)
2 El usuario deberá pulsar en un chat que se encuentre en la lista de Chats Activos o Chats Entrantes
3 El usuario deberá teclear un mensaje en el campo de texto de la parte inferior, y pulsar el botón de enviar
Figura 36. CU-08
Página 39
CU-09
Precondición Los usuarios deben haber iniciado sesión previamente
Descripción Aumentar el progreso de una conversación de chat para esclarecer la imagen de perfil del otro usuario y llenar la barra de progreso
Actor 1 Usuario de la aplicación que haya iniciado sesión
Actor 2 Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El Actor 1 deberá ir a la pantalla de chat individual con el Actor 2
2 El Actor 1 deberá enviar un mensaje escribiendo en el campo de texto de la parte inferior de la pantalla
3 El Actor 2 deberá responder al mensaje para aumentar el progreso de la conversación entre Actor 1 y Actor 2
Figura 37. CU-09
CU-10
Precondición El usuario debe haber iniciado sesión previamente
Descripción Ver el perfil de un usuario
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá navegar a la pantalla de chat individual con otro usuario
2 El usuario deberá pulsar la imagen de perfil del otro usuario
3 El actor será redirigido al perfil del otro usuario
Figura 38. CU-10
Página 40
CU-11
Precondición El usuario debe haber iniciado sesión previamente
Descripción Realizar una búsqueda
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá pulsar el campo de texto con el logotipo en barra superior de la pantalla
2 El usuario deberá introducir uno o varios términos a buscar
3 El usuario deberá pulsar el botón de enviar en el teclado estándar del dispositivo
4 El usuario es redirigido a la pantalla de resultados
Figura 39. CU-11
CU-12
Precondición El usuario debe haber iniciado sesión previamente
Descripción Cerrar sesión
Actor Usuario de la aplicación que haya iniciado sesión
Secuencia Normal Paso Acción
1 El usuario deberá abrir el menú lateral izquierdo
2 El usuario deberá pulsar el botón “Cerrar sesión”, ubicado en la parte inferior del menú lateral izquierdo
Figura 40. CU-12
Página 41
3.4. Análisis y diseño de la interfaz de usuario
La interfaz gráfica es una de las partes más fundamentales e importantes de la aplicación. Por esto, la interfaz de esta aplicación ha sido diseñada para ser lo más sencilla posible para el usuario, con la mínima cantidad de “lag” o retrasos en las respuestas táctiles, navegación, carga, etc.
Combina un estilo plano con algunos elementos de Material Design en Android para ofrecer una experiencia personalizada pero ante todo familiar para el usuario. La utilización de elementos estándar de navegación y de interfaz también ayuda a la sencillez de uso.
El problema de una interfaz en React Native:
React Native ejecuta en un único hilo el código desarrollado en JavaScript que creamos para diseñar el proyecto. Esto trae algunas consecuencias, como por ejemplo, el retraso en las animaciones que se encuentran en la aplicación (de pantalla a pantalla, botones, cartas…).
Las animaciones tienen que pasar por “el puente” JavaScript - nativo para realizar una animación. Dicho de otra manera, por cada posición que se quiere que pase el componente que se va a animar, es necesario comunicarse con la parte nativa (el UI Thread en Android/iOS) de la aplicación para mover el componente nativo. Si además estamos ejecutando algo más en el hilo JavaScript, como por ejemplo una llamada HTTP o alguna tarea medianamente costosa, puede llegar a retrasar esa comunicación.
En la mayoría de veces esto no suponía ningún problema, pero cuando se comenzaba a juntar las tareas y a realizar varias animaciones simultáneas, se podía empezar a observar el retraso general de todos los procesos.
Esto iba en contra de lo que se quería conseguir con el diseño de la interfaz de la aplicación: que tuviera la mínima cantidad de retraso (o “lag”) posible (limitado a la carga de datos del API remoto, y aún así, en estos casos se mostraría un indicador de progreso para avisar al usuario). Tan importante fue dicho problema que se puso en consideración el cambiar a realizar la aplicación de forma nativa en Android, y abandonar la parte de iOS.
La solución encontrada:
Afortunadamente, este problema ya ha sido tratado en React Native, y mediante el atributo useNativeDriver=true, es posible delegar estas animaciones en su totalidad al UI Thread nativo. Esto permite que las tareas en ejecución en JavaScript continúen su curso mientras que se realiza la animación en el hilo de interfaz nativo. El resultado: unas animaciones fluidas.
Página 42
3.4.1 Vista Previa de la Interfaz
Figura 41. Pantalla de inicio
Página 43
Figura 42. Pantalla de registro
Página 44
Figura 43. Pantalla de publicar
Página 45
Figura 44. Pantalla de publicar (2)
Página 46
Figura 45. Visualización de una publicación
Página 47
Figura 46. Pantalla de chat individual
Página 48
3.4.2 Tipos de Navegación
La navegación en la aplicación se puede realizar de tres modos:
● Navegación directa. Mediante código se decide cuándo pasar a la siguiente pantalla. Por ejemplo, en la pantalla de inicio de sesión, al darle click al botón, desde código se navega a la pantalla principal.
● Navegación con tabs o pestañas (BottomTabs). Al iniciar sesión, se navega entre pantallas mediante pestañas en la parte inferior de la pantalla.
Figura 47. Barra de navegación
● Navegación con Drawer. Al deslizar la parte izquierda de la pantalla se despliega un menú lateral con enlaces para navegar a otras páginas (distintas que las de las pestañas / tabs).
Página 49
3.4.3 Diagrama de Navegación
A continuación se muestra el diagrama de navegación de la aplicación detallando las posibles rutas que el usuario puede tomar dentro de ella:
Figura 48. Diagrama de Navegación entre pantallas
Aspectos relevantes
● En las flechas se especifica cómo puede el usuario navegar de una pantalla a otra. Mediante Tabs, Drawer o navegación directa (al pulsar en botones, imágenes, etc…).
● Las únicas pantallas accesibles sin el usuario haber iniciado sesión son: SplashScreen, ForgotScreen y SignupScreen. Las demás pantallas necesitan de autenticación.
Página 50
3.4.4 Componentes de interfaz gráfico
La interfaz de usuario está compuesta de múltiples componentes separados por módulos en la aplicación. Cada componente tiene una funcionalidad diferenciada y obtiene la información mediante props , en las que se pasa información desde cada una de las pantallas que los emplea. 25
Componente Descripción Imagen
Avatar La imagen de perfil de un usuario y la barra de progreso circular alrededor de la imagen. También gestiona el cambio de imagen de perfil.
Button Componente de botón que soporta tres estilos: fondo rosa, fondo blanco, y contorno blanco.
Emoji Componente que muestra un emoji.
Header Componente de cabecera que incluye la barra de búsqueda y gestiona las búsquedas realizadas en ella.
Modals/Progress Pantalla modal de carga.
Lists/Chat Componente de una fila de la lista de chats y de mensajes en un chat determinado.
25 https://facebook.github.io/react-native/docs/props.html Propiedades en React.
Página 51
Lists/Posts Componente de una publicación (Post) de las “cartas” de la pantalla principal.
OAuth Componente WebView para permitir la autenticación mediante OAuth con Facebook, Twitter, Instagram, y otros.
Pill Componente sencillo de navegación entre dos pantallas.
Sidebar Componente que forma el menú de navegación lateral.
User Componente que muestra el Avatar del usuario, y otros datos. Se utiliza en el componente Sidebar.
Página 52
Figura 49. Tabla de componentes de interfaz
3.4.5 Colores
La aplicación utiliza los siguientes colores como colores principales, aparte de blanco (#fff), negro (#000) y varias tonalidades de gris, que también son ampliamente utilizados:
#fe5252 #59d46e
Figura 50. Colores de la aplicación
El verde se utiliza en componentes del interfaz que indican progreso o éxito. Por ejemplo, la barra de progreso de las imágenes de perfil. El rosa melocotón se utiliza para dar acento a textos y fondos con texto blanco superpuesto.
Ambos colores provienen directamente del logotipo , para darle una apariencia uniforme a toda la aplicación en cuanto a la coloración.
3.4.6 Tipografía
Uno de los pasos del diseño de una interfaz es la elección de tipografía que se va a utilizar en las distintas pantallas y componentes. La tipografía es lo que da un toque diferente y personal a cada aplicación.
No es suficiente con utilizar una tipografía que nos guste por cuestiones de estilo, sino que también hay que tener en cuenta la legibilidad de las mismas.
Al tratarse de una aplicación móvil, conocemos la familia tipográfica que se va a mostrar por defecto en Android e iOS. En el caso de Android, es Roboto , y en caso de iOS (desde la versión 9), 26
San Francisco . 27
26 https://en.wikipedia.org/wiki/Roboto Tipografía de Google 27 https://developer.apple.com/fonts/ Tipografía de Apple
Página 53
Figura 51. Roboto Figura 52. San Francisco
Estas tipografías son perfectamente legibles, y por tanto, se ha decidido utilizarlas como la
tipografía principal, utilizadas para textos de mediana a larga longitud. En cuanto a la tipografía de títulos, se ha decidido utilizar una combinación de Gotham y Gotham Rounded.
Figura 53. Gotham
Página 54
La variante Rounded se utiliza en títulos de tamaño mediano y texto de poca longitud de caracteres, y en los botones (20p), mientras que la normal se utiliza para títulos de gran tamaño (30p en adelante), visibles en los títulos de algunas pantallas, como el de publicar un post.
Figura 54. Ejemplo tipografía 1 Figura 55. Ejemplo tipografía 2
Combinación de Gotham Rounded y Roboto Combinación de Gotham y Roboto
Página 55
Capítulo 4
Implementación
4.1 Estructura de ficheros
4.1.1 Cliente
📂 android 📂 ios 📂 app
📂 Assets 📂 Components
📂 Avatar 📄 AnimatedCircularProgress.js 📄 CircularProgress.js 📄 index.js
📂 Button 📄 Index.js 📄 styles.js
📂 Lists 📂 Chat
📄 index.js 📂 Posts
📄 index.js 📂 Emoji
📄 index.js 📂 OAuth
📄 index.js 📂 Pill
📄 Index.js 📄 styles.js
📂 Containers 📂 About
📄 index.js
Página 56
📂 Chat 📄 index.js
📂 ChatList 📄 index.js
📂 Explore 📄 index.js
📂 Forgot 📄 index.js
📂 Header 📄 index.js
📂 Sidebar 📄 index.js
📂 Post 📄 index.js
📂 Profile 📄 index.js
📂 Settings 📄 index.js
📂 Signup 📄 index.js
📂 Splash 📄 index.js
📂 Stores 📄 AuthenticationStore.js 📄 APIStore.js 📄 LanguageStore.js 📄 GeolocationStore.js 📄 index.js
📂 Services 📄 PushNotifications.js 📄 index.js
📂 I18n 📄 en-US.json 📄 es-ES.json 📄 index.js
📂 Navigation 📄 DrawerNavigation.js 📄 StackNavigation.js 📄 TabNavigation.js
Página 57
📄 app.json 📄 package.json 📄 index.js (Punto de Entrada de Aplicación)
Figura 56. Estructura de ficheros de cliente
4.1.2 Servidor
📂 Middleware 📄 ProtectedResource.js 📄 CreationRequest.js 📄 AuthenticationRequest.js 📄 index.js
📂 Models 📄 Message.js 📄 Post.js 📄 Profile.js 📄 User.js 📄 index.js
📄 PeachyServer.js 📄 HTTPAPI.js 📄 WebSocketAPI.js 📄 ext.js 📄 index.js (Punto de Entrada de Aplicación)
Figura 57. Estructura de ficheros de servidor
Página 58
4.2 Descripción de directorios y ficheros
4.2.1 Cliente
android
Directorio en el que se encuentra el código nativo a la plataforma Android, en Java.
ios
Directorio en el que se encuentra el código nativo a la plataforma iOS, en Objective-C.
app
Es la carpeta principal del proyecto. Directorio en el que se encuentra todo el código JavaScript de la aplicación.
app ⇒ assets
Directorio en el que se encuentran todas las imágenes, y otro contenido multimedia local que utiliza la aplicación.
app ⇒ components
Directorio en el que se encuentran los componentes React de la aplicación.
app ⇒ components ⇒ Avatar ⇒ index.js
Componente de imagen de perfil de un usuario.
Página 59
app ⇒ components ⇒ Avatar ⇒ AnimatedCircularProgress.js
Componente interno de Avatar, que representa un círculo de color alrededor de la imagen para indicar progreso. Variante animado.
app ⇒ components ⇒ Avatar ⇒ CircularProgress.js
Componente interno de Avatar, que representa un círculo de color alrededor de la imagen para indicar progreso. Variante sin animación.
app ⇒ components ⇒ Button ⇒ index.js
Componente de botón de la interfaz.
app ⇒ components ⇒ Button ⇒ styles.js
Fichero de estilos del componente de botón.
app ⇒ components ⇒ Emoji ⇒ index.js
Componente iconográfico de emoji.
app ⇒ components ⇒ Lists
Directorio en el que se encuentran los distintos elementos de listas de la aplicación.
app ⇒ components ⇒ Lists ⇒ Chat ⇒ index.js
Elementos de listas de la pantalla de chat individual.
Página 60
app ⇒ components ⇒ Lists ⇒ Posts ⇒ index.js
Elementos de lista de publicaciones de la pantalla principal.
app ⇒ components ⇒ OAuth ⇒ index.js
Componente de autenticación OAuth. (Sin utilizar)
app ⇒ components ⇒ Pill ⇒ index.js
Componente de pastilla.
app ⇒ containers ⇒ About ⇒ index.js
Pantalla de “Sobre Peachy”, con información sobre la aplicación.
app ⇒ containers ⇒ Chat ⇒ index.js
Pantalla individual de chat.
app ⇒ containers ⇒ ChatList ⇒ index.js
Pantalla de listado de chats.
app ⇒ containers ⇒ Explore ⇒ index.js
Pantalla principal de la aplicación donde se muestran las publicaciones.
Página 61
app ⇒ containers ⇒ Forgot ⇒ index.js
Pantalla para la recuperación de cuenta del usuario en caso de pérdida.
app ⇒ containers ⇒ Header ⇒ index.js
Componente de cabecera que incluye la barra de búsqueda. Se muestra en todas las pantallas internas (al haber iniciado sesión).
app ⇒ containers ⇒ Sidebar ⇒ index.js
Componente de barra lateral que se muestra al abrir el Drawer (menú lateral).
app ⇒ containers ⇒ Post ⇒ index.js
Pantalla de formulario de publicación.
app ⇒ containers ⇒ Profile ⇒ index.js
Pantalla de perfil de usuario.
app ⇒ containers ⇒ Settings ⇒ index.js
Pantalla de ajustes del usuario.
app ⇒ containers ⇒ Signup ⇒ index.js
Pantalla de creación de usuario.
Página 62
app ⇒ containers ⇒ Splash ⇒ index.js
Pantalla de carga inicial. También incluye la pantalla de inicio de sesión, pero ésta se oculta/descubre dependiendo si el usuario ya ha iniciado sesión.
app ⇒ stores
Directorio en el que se encuentran los distintos almacenes de información de la aplicación. Contienen valores @observables que hacen actualizar los componentes de la interfaz gráfica. También contienen las métodos de llamadas HTTP y WebSockets para obtener datos.
app ⇒ stores ⇒ AuthenticationStore.js
Almacén de información que obtiene / almacena los datos relacionados a la autenticación del usuario. Esto incluye: inicio de sesión, cierre de sesión.
app ⇒ stores ⇒ APIStore.js
Almacén de información que obtiene / almacena los datos relacionados a APIs remotos, ya sea el API del servidor Express o el API del servidor de WebSockets. Permite la comunicación bidireccional con el servidor.
app ⇒ stores ⇒ LanguageStore.js
Almacén que contiene los métodos para obtener cadenas de caracteres traducidas de los ficheros de traducción (es-ES.json, en-US.json).
app ⇒ stores ⇒ GeolocationStore.js
Almacén que obtiene y almacena los datos de localización del usuario.
Página 63
app ⇒ services
Directorio en el que se encuentran las herramientas que utilizan servicios externos. Actualmente solo existe el de FCM (Firebase Cloud Messaging) para las notificaciones push.
app ⇒ services ⇒ PushNotifications.js
Utilidad que permite registrar el código de dispositivo del usuario para posteriormente enviarle notificaciones push mediante FCM (Firebase Cloud Messaging).
app ⇒ i18n
Directorio en el que se encuentran los ficheros de traducción.
app ⇒ i18n ⇒ en-US.json
Fichero de lenguaje en inglés (Estados Unidos).
app ⇒ i18n ⇒ es-ES.json
Fichero de lenguaje en castellano (España).
app ⇒ navigation
Directorio en el que se encuentran los componentes de navegación (StackNavigator, TabNavigator y DrawerNavigator), que se ocupan de gestionar la navegación dentro de la aplicación.
app ⇒ navigation ⇒ StackNavigation.js
Componente que gestiona la navegación directa dentro de la aplicación.
Página 64
app ⇒ navigation ⇒ DrawerNavigation.js
Componente que gestiona la navegación mediante el menú lateral.
app ⇒ navigation ⇒ TabNavigation.js
Componente que gestiona la navegación mediante pestañas.
package.json
Fichero en el que se encuentran las dependencias del proyecto.
index.js
Punto de entrada de la aplicación.
4.2.2 Servidor
middleware
Directorio en el que se encuentra el middleware de Express. Se ejecutan antes de cualquier llamada a rutas del API, si así está definido en la propia ruta.
middleware ⇒ CreationRequest.js
Middleware que comprueba los campos necesarios para una petición para crear un usuario.
middleware ⇒ ProtectedResource.js
Middleware que comprueba que el cliente intentando acceder a la ruta está autenticado.
Página 65
middleware ⇒ AuthenticationRequest.js
Middleware que comprueba los campos necesarios para una petición de iniciar sesión (u obtener un token de autenticación).
models
Directorio en el que se encuentran los modelos de base de datos MongoDB. Cada clase de modelo contiene su Schema de MongoDB, y métodos CRUD para gestionar la información.
models ⇒ User.js
Modelo que representa a un usuario de la aplicación.
models ⇒ Profile.js
Modelo que representa a un perfil de usuario de la aplicación.
models ⇒ Post.js
Modelo que representa a una publicación de la aplicación
models ⇒ Message.js
Modelo que representa un mensaje enviado entre dos usuarios de la aplicación.
PeachyServer.js
Clase principal del proyecto que acepta como parámetros un servidor HTTP y un servidor WebSocket.
Página 66
HTTPAPI.js (Express)
Fichero en el que se encuentran todas las rutas del API REST.
WebSocketAPI.js
Fichero en el que se encuentra el servidor API de WebSocket.
ext.js
Fichero general que contiene métodos de ayuda de distinto tipo.
index.js
Punto de entrada de la aplicación.
package.json
Fichero en el que se encuentran las dependencias del proyecto.
4.3 Funcionamiento del bloqueo de imagen
La funcionalidad especial de Peachy es que nos permite conocer a gente sin ver la foto inicialmente. Para poder ver la imagen, será necesario desbloquearla mediante un sistema de progreso mediante la conversación con el usuario mediante la funcionalidad en tiempo real de chat.
Para evitar trampas, el acceso API a las imágenes de perfil requiere de autenticación. El API recibe una petición de una imagen de perfil, recoge la imagen de base de datos, calcula el progreso entre los usuarios (el usuario que solicita la imagen, y el usuario al que se le está solicitando), y aplica a la imagen el difuminado correspondiente al progreso calculado.
Página 67
Figura 58. Obtención de una imagen de perfil del servidor
El progreso en sí es calculado mediante la búsqueda de intercambios mutuos. Es decir, pares
de mensajes enviados y respondidos. De esta forma los mensajes enviados repetidamente no cuentan de cara al progreso.
const mutualExchange100percent = 150; // valor arbitrario
const messages = Message.find({ $or: [ {
senderId: _id1,
recipientId: _id2
},
{
senderId: _id2,
recipientId: _id1
}
]
});
let mutualExchanges = 0;
Página 68
for (let i = 0; i < messages.length; i++) { if (i == messages.length - 1) continue;
const thisMessage = messages[i]; const nextMessage = messages[i + 1]; const nextSenderUserId = thisMessage.senderId == _id1 ? _id2 : _id1;
if (nextMessage.senderId == nextSenderUserId) { mutualExchanges++;
}
}
return (mutualExchanges / mutualExchange100percent) * 100;
Figura 59. Función de cálculo de progreso
1. Se realiza una búsqueda de todos los mensajes intercambiados. 2. Se comprueba de forma síncrona que cada mensaje haya sido seguidamente respondido por
el usuario contrario. 3. Si el mensaje ha sido respondido, se incrementa mutualExchanges. 4. Al final se calcula el porcentaje de progreso de la conversación y se devuelve.
Página 69
Capítulo 5
Documento de Cierre 5.1 Conclusiones
Peachy es una manera distinta y nueva de conocer a gente, sin dar importancia a los selfies, sin tener que hacer 200 fotos para ver en cuál se sale mejor, y sin tener que aparentar. Lo que importa al final del día es el interior de cada persona y las conversaciones de cada día, y es lo que se ha querido impulsar con Peachy. Conoce gente de verdad y ten conversaciones genuinas. “Leave your pics out of the picture”.
Peachy no es tan solo innovador en cuanto a su funcionamiento, sino también en cómo ha sido desarrollado, utilizando las últimas tecnologías disponibles para el desarrollo de aplicaciones multiplataforma. Para poder desarrollar esta aplicación, se ha tenido que invertir mucho tiempo en investigación para encontrar el framework de desarrollo más óptimo y correcto para la tarea.
Tras la exhaustiva búsqueda, balanceando los pros y contras entre frameworks como NativeScript, Xamarin (framework que iba a ser utilizado en un principio), Ionic, PhoneGap, y otros, apareció React Native, una solución comparable en rendimiento a Xamarin o incluso una aplicación totalmente nativa, utilizando el lenguaje JavaScript, y la arquitectura de React que ya conocía tras haber jugado con ella en proyectos personales orientados a web.
React Native ha resultado ser una solución muy eficaz y con una corta curva de aprendizaje, sobre todo si has utilizado React.js anteriormente. Es posible crear aplicaciones que lucen la misma apariencia en Android e iOS cambiando mínimamente el código para cada plataforma, con un rendimiento muy óptimo en ambos, comparable con aplicaciones nativas.
No hay cliente sin servidor, y por tanto, para el servidor, tras elegir React Native, no dudé en utilizar Node.js para la tarea, utilizando el framework Express para el API. Es la tecnología que más estoy utilizando en mis proyectos personales actualmente, y al utilizar Node.js, el cliente y el servidor están en el mismo lenguaje (JavaScript), haciendo el desarrollo mucho más sencillo y llevadero sin tener que cambiar de lenguaje.
Página 70
Sin duda el MERN stack (MongoDB + Express.js + React Native + Node.js) será mi stack de preferencia para crear aplicaciones en el futuro, y estoy muy contento de haber elegido estas tecnologías para este proyecto y haber aprendido su funcionamiento en profundidad.
5.2 Proyecciones del futuro
A pesar de que la aplicación, en su estado actual, es un producto completo en sí, se destacan algunos aspectos a considerar en el futuro para expandir con facilidad la funcionalidad de la aplicación.
5.4.1 Publicidad no intrusiva
La aplicación en su estado actual no tiene publicidad, pero hay varios lugares en los que se pueden implementar mediante Google AdMob, y de una manera que no interrumpa demasiado la experiencia del usuario en la aplicación.
Para poder utilizar AdMob, es necesario configurar tu cuenta de Google en https://apps.admob.com/?pli=1.
Para mostrar los banners de AdMob, se puede utilizar el paquete react-native-admob para cargar los banners de Google AdMob y mostrarlos en el cliente.
Carrusel de la pantalla principal
En la pantalla principal el usuario puede ver las publicaciones que han creado otros usuarios. Estos se muestran en formato carrusel, en el que el usuario puede deslizar la carta hacia la derecha para ver la siguiente, o hacia la izquierda para ver la anterior. Estas cartas se van cargando a medida que el usuario las va pasando mediante un sistema de paginación
Es posible introducir una carta que contenga un anuncio del tamaño total de la carta cuando el usuario haya cargado un número determinado de cartas, modificando el archivo ApiStore.js para incluir la lógica en el método de cargado de publicaciones.
Barra de navegación lateral (Sidebar)
Esta barra lateral también es buen lugar para mostrar anuncios cuadrados de pequeño tamaño, entre los enlaces y el botón de cerrar sesión.
Página 71
5.4.2 Funcionalidades extra al componente de Chat
La funcionalidad de chat de la aplicación, en el estado actual, no permite compartir nada más que mensajes. Todas las aplicaciones de mensajería incluyen alguna manera de compartir imágenes, videos, y más contenido multimedia. Aunque no sea el enfoque principal de la aplicación el compartir nada más que mensajes, se podría añadir la funcionalidad con relativa sencillez.
En cuanto al cliente, sería necesario modificar el archivo Containers/Chat/index.js para incluir los elementos de interfaz gráfico para compartir contenido multimedia (por ejemplo, iconos). La lógica de procesamiento de la petición se realizaría en el archivo Stores/ApiStore.js.
En principio se podría almacenar el contenido multimedia directamente en la base de datos de Mongo, siempre y cuando el contenido no exceda los 16 MB. Puede parecer poco tamaño para vídeos especialmente, pero quizá también interese tener esta limitación para no saturar el procesamiento del servidor. Se crearía en el modelo Message.js del servidor un nuevo campo para contenido multimedia, en el que se almacenaría el contenido en binario, junto con el tipo de dato como una cadena de texto.
En cuanto al servidor, los cambios necesarios ya estarían realizados. El servidor API continuará sirviendo los mensajes de forma habitual, incluyendo el campo de contenido multimedia, que el cliente podrá consumir al recibir una lista de mensajes de un chat mediante la carga inicial del chat o mediante un mensaje recibido en tiempo real mediante sockets.
En el cliente, para mostrar el contenido multimedia, será necesario utilizar paquetes externos para cada tipo de contenido. https://github.com/react-native-community/react-native-video, por ejemplo, permite mostrar videos con una barra de controles. Sería necesario modificar el archivo Components/Lists/Chat/index.js para incluir la funcionalidad de estos paquetes que muestran contenido multimedia en el mensaje.
5.4.3 Plataforma web atacando el Express API
Una de las ventajas de utilizar un API REST para el backend de la aplicación es que es completamente reutilizable para ser consumida desde cualquier otra plataforma, por ejemplo, web.
Además, al utilizar Express, no es necesario cambiar de lenguaje ni tecnología para implementar una aplicación web. Express mismo puede servir las páginas con sus respectivo
Página 72
código HTML, JavaScript, CSS y otro contenido estático. El servidor Express contendría, pues, toda la lógica de procesamiento del API, y además, el servicio de la parte visual de la aplicación web.
Otro gran aliciente - Al utilizar React Native, se utiliza la arquitectura de React para
desarrollar aplicaciones. React también está disponible para web, en forma de React.js, un framework para desarrollar aplicaciones web con esta arquitectura. De esta forma, no hará falta ni siquiera cambiar de arquitectura o de framework a la hora de desarrollar para la plataforma web.
5.4.4 Nueva funcionalidad: Guardar a favoritos
Una nueva funcionalidad de las muchas que se pueden realizar en la aplicación es el guardado a favoritos, en el que se permite al usuario guardar publicaciones para ver después.
Esto implicaría algunos cambios en el cliente y el servidor. Se pueden resumir en las siguientes tareas:
● Crear nuevo modelo Bookmark en la capa de datos del servidor, con al menos el identificador de la publicación (modelo Post) y el identificador del usuario.
● Crear los métodos CRUD en el modelo de creación y consulta, y exportarlos (module.exports).
● Crear una ruta de procesamiento en el API para obtener los favoritos de la base de datos, y otra ruta para crear uno nuevo. Si se desea, se puede aprovechar la misma ruta (por ejemplo: /api/bookmarks), dividido en acción GET (para obtener los favoritos) y POST (para crear uno). A esta ruta de procesamiento se añadirá también el middleware de Token (M.Token), puesto que se requiere que el usuario esté autenticado para gestionar sus favoritos.
● En el cliente, se añadirán los métodos de gestión de favoritos en el APIStore.js, los cuales utilizarán axios para realizar las peticiones HTTP a la ruta del API que se ha creado anteriormente.
Para representar los datos obtenidos en el UI, sería necesario crear una propiedad @observable en el APIStore para que almacene todos los favoritos que se obtengan. Esta propiedad se podrá bindar después a una lista (FlatList) para mostrarlos.
Por último, hará falta añadir un botón que desencadenará la acción de guardar una publicación como favorito. Se puede añadir en el archivo Components/Lists/Post.js.
Página 73
5.4.5 Integración contínua con Microsoft Visual Studio App Center
Mediante la implementación de integración contínua en la aplicación, se podrá lanzar actualizaciones de la aplicación de forma automática. Esto incluye la compilación para ambas plataformas y comprobación del código. No es necesario implementarlo, pero reduce drásticamente el tiempo necesario para desplegar una actualización en las tiendas de aplicaciones.
La herramienta disponible para implementar integración contínua en React Native es Visual Studio App Center.
https://docs.microsoft.com/en-us/appcenter/sdk/getting-started/react-native
5.4.6 Sistema de invitaciones
Es posible restringir el uso de la aplicación únicamente a usuarios que hayan recibido una invitación. Esta comprobación se haría durante el registro, contra una colección de la base de datos que contenga todos los códigos generados por el método que se decida (preferentemente GUIDs).
Se puede realizar una pantalla donde los usuarios puedan generar sus propios códigos para compartirlos, y otra pantalla para aquellos que los reciban, para que puedan introducirlos y obtener acceso a la pantalla de registro de la aplicación.
5.4.7 Sistema de progreso más robusto
Para calcular el progreso de conversación entre dos usuarios, la aplicación se limita, en su estado actual, a buscar pares de mensajes enviados y respondidos, o lo que es lo mismo, intercambios mutuos.
Es posible extender esta funcionalidad e incluir/sustituirlo por un análisis sentimental del cuerpo de los mensajes. Existen librerías que facilitan mucho el trabajo para ello, como WordNet 28
para Node.js, que devuelve un valor entre 0 y 1, 0 indicando un mensaje con valor sentimental positivo, y 1 indicando negatividad.
28 http://www.lexicadb.com/lxserver/wn_js.html#synset_sentiment Calcular el valor sentimental de un texto con WordNet y JavaScript.
Página 74
BIBLIOGRAFÍA
❏ https://reactjs.org/tutorial/tutorial.html Tutorial: Intro To React. ❏ https://facebook.github.io/react-native/docs/tutorial.html Learn the Basics · React
Native ❏ https://www.tutorialspoint.com/react_native/ React Native Tutorial. ❏ https://code.facebook.com/posts/895897210527114/dive-into-react-native-perf
ormance/ Dive into React Native performance ❏ https://medium.com/@Osterberg/react-native-performance-optimization-and-pr
ofiling-5b586e9018f8 React Native Performance Optimization and Profiling ❏ http://mongoosejs.com/docs/ Mongoose v5.1.3: Getting Started ❏ http://mongoosejs.com/docs/faq.html Mongoose FAQ ❏ https://docs.mongodb.com/manual/faq/ MongoDB FAQ ❏ https://hackernoon.com/xamarin-vs-react-native-a-comparison-study-5ebea64c
d801 Xamarin vs React Native: A Comparison Study ❏ https://codeburst.io/react-native-vs-real-native-apps-ad890986f1f React Native
vs Real Native Apps ❏ https://hackernoon.com/mongodb-vs-mysql-comparison-which-database-is-bet
ter-e714b699c38b MongoDB vs MySQL Comparison: Which Database is Better?
Página 75
Anexos
Página 76
Anexo I - Manual técnico de instalación
Instalación y ejecución del servidor
El servidor es compatible con los sistemas operativos Windows Server y Linux en cualquiera de sus distros puesto que utiliza Node.js, tecnología compatible con ambos sistemas. No obstante, en este manual se detallará la instalación en Windows Server, puesto que es el sistema operativo que se ha utilizado para desplegarlo en producción, pero las instrucciones pueden seguir para Linux de similar forma.
1. Instalación y configuración de Node.js
La instalación de Node.js es muy sencilla. Únicamente habrá que visitar el siguiente enlace para descargar el instalador oficial de Node.js en sistemas Windows. El mismo instalador está disponible para Linux.
https://nodejs.org/en/download/
2. Instalación y configuración de MongoDB Server
El servidor requiere de MongoDB puesto que es el SGBD que utiliza para almacenar la información de la aplicación. El instalador de MongoDB se encuentra en su página oficial, y al igual que Node.js, posee instaladores automáticos para Windows y Linux.
3. Obtención y preparación del código fuente
Puedes utilizar el código fuente que se te ha proporcionado con esta documentación, que se debería encontrar en el directorio II. Código Fuente/II-II. Servidor.
Puedes también obtener el paquete completo en línea accediendo al enlace https://peachyapp.co/source.zip
E identificándose como Usuario: PEACHY2018 Contraseña: DAMDUAL
El directorio no contiene las dependencias de la aplicación de servidor para reducir el tamaño total del proyecto. Por este motivo deberemos instalarlos mediante la herramienta de gestión de paquetes de Node.js, npm (Node Package Manager). Este viene instalado por defecto con la instalación regular de Node.js.
Página 77
Para realizar la instalación de los paquetes, bastará con iniciar la consola de comandos y navegar al directorio del servidor. Una vez nos encontremos en ella, podemos ejecutar el comando npm install para instalar todas las dependencias automáticamente.
Al finalizar, ya es posible ejecutar el servidor, ejecutando el comando node index. La línea de comandos no mostrará ningún mensaje para indicar que está funcionando puesto que no se ha activado el modo debug. Para hacer esto, haremos CTRL + C para cerrar la instancia del servidor si está corriendo, y ejecutaremos el comando SET DEBUG=peachy*.
Tras ejecutar el comando para crear la variable de entorno DEBUG, se mostrarán mensajes relevantes a las acciones que realiza / recibe el servidor, como errores controlados.
Ejecución del cliente
La aplicación está desarrollada con React Native, una tecnología multiplataforma. Aunque sea una tecnología multiplataforma, es necesario tener una máquina con Windows o MacOS si queremos compilar para Android, y, obligatoriamente MacOS si queremos compilar para iOS.
Dicho de otra manera, si únicamente disponemos de una máquina Windows, únicamente podremos compilar / debuguear la aplicación para Android. Si disponemos de una máquina MacOS, podremos hacerlo para ambas plataformas, Android e iOS. Esto sucede porque iOS no es compatible con Windows de ninguna forma emulable o virtualizable, sin embargo, Android sí lo es para MacOS.
Este problema se puede solucionar (si sólo se dispone de una máquina Windows, que es lo habitual) mediante una máquina virtual de MacOS. No obstante, esto es ilegal puesto que Apple permite únicamente la virtualización / emulación de su sistema operativo MacOS en sistemas que tengan hardware de Apple.
Ejecución de la aplicación con Genymotion
Para poder ejecutar la aplicación en una máquina virtual Android con Genymotion, basta con descargar e instalar Genymotion desde: https://www.genymotion.com/, crear una máquina virtual en la versión de Android que queramos, e iniciarlo.
Para cargar la aplicación, habrá que, desde la línea de comandos, ejecutar el comando react-native run-android, estando en el directorio raíz del cliente. Tras realizar una compilación debug, se abrirá la aplicación en la máquina virtual.
Página 78
Anexo II - Cuaderno de Bitácora 01/04/2018
● Investigación de React Native 3h ● Lectura de documentación 1h
○ https://facebook.github.io/react-native/docs/components-and-apis.html ○ https://facebook.github.io/react-native/
● Tutoriales 0,5 h ○ https://facebook.github.io/react-native/docs/tutorial.html
02/04/2018
● Investigación de React Native 2h ● Lectura de documentación 2h
○ https://facebook.github.io/react-native/ ● Tutoriales 2h
○ https://www.tutorialspoint.com/react_native/index.htm 03/04/2018
● Lectura de documentación de React Native 3h ● Realizar pruebas siguiendo la documentación 1h
04/04/2018
● Generación de cliente de aplicación 2h ○ https://facebook.github.io/react-native/docs/getting-started.html
● Diseñar prototipo a papel 1h ● Determinar la arquitectura 1h
05/04/2018
● Determinar las librerías necesarias 2h ● Determinar API de servidor 3h
○ https://expressjs.com/ ○ https://hapijs.com/ ○ C# ASP.NET
06/04/2018
● Inicio de propuesta de proyecto 3h ● Inicio de documentación 1,5h
○ Portada
Página 79
○ Introducción ○ Requisitos funcionales / no funcionales
07/04/2018
● Creación de pantallas de aplicación básicas [Diseño] 2h ● Determinar e investigar librería de navegación 2h
○ React Navigation https://reactnavigation.org/ ○ React Native Navigation (wix) https://github.com/wix/react-native-navigation
● Realizar pruebas con ambas librerías de navegación 1,5h 08/04/2018
● Dar estilo a las pantallas básicas [Diseño] 3h ● Integración de librería de navegación [Diseño] 2h ● Determinar e investigar librería de gestión de estados 0,5h
○ Redux ○ MobX
09/04/2018
● Intento de implementación de Redux 1h ● Cambio de Redux a MobX e implementación de MobX en la aplicación de cliente 3h
10/04/2018
● Implementación de la librería de navegación, personalización de animaciones [Diseño] 5h
11/04/2018
● Inicio de código de servidor con Express.js [Implementación] 2h ● Creación de rutas básicas y realización de pruebas con Postman [Diseño,
Implementación] 2h ○ /api/test
12/04/2018
● Iniciada la comunicación cliente - servidor API [Implementación] 4h ○ /api/login ○ /api/signup
● Pruebas con Postman [Pruebas] 2h 12/04/2018
● Documentación 4h ○ Tareas ○ Metodología ○ Planificación temporal
Página 80
13/04/2018
● Investigación de base de datos 3h ○ MySQL ○ SQLite ○ MongoDB
● Pruebas con cada SGBD y Express, pruebas de velocidad con varios registros 2h 14/04/2018
● Elección de MongoDB ● Implementación de MongoDB con Express 5,5h
16/04/2018
● Creación de los Stores e integración con el servidor [Implementación] 5h: ○ AuthenticationStore ○ APIStore
17/04/2018
● Documentación 3h ○ Tecnologías utilizadas ○ Modelo Entidad Relación [Diseño] 1h
● Diseño de modelos de base de datos [Diseño] 5h
○ User ○ Post ○ Profile ○ Message
18/04/2018
● Creación de un flujo de autenticación provisional (de pruebas) 3h ● Investigación sobre métodos de autenticación 4h
○ JWT https://jwt.io/introduction/ ○ Cookies
19/04/2018
● Elección de JWT e implementación en el API 4h 20/04/2018
● Implementación de JWT en el cliente [Implementación] 4h ● Finalización del flujo de autenticación final con JWT [Implementación] 1h ● Investigar solución para tiempo real 1h
Página 81
○ WebSockets ○ Long-Polling
21/04/2018
● Implementación de WebSockets en el servidor [Implementación] 5h ● Pruebas con WebSockets 0,5h
23/04/2018
● Configuración de Firebase Cloud Messaging [Implementación] 0,5h ● Configuración de Nodemailer [Implementación] 0,5h ● Implementación de FCM y notificaciones Push en el servidor [Implementación] 4h
24/04/2018
● Implementación de Nodemailer en el servidor [Implementación] 4h ● Configuración de Mailgun [Implementación] 0,5h ● Pruebas de envíos de correos [Pruebas] 2h
25/04/2018
● Creación de los Stores [Implementación] 3h: ○ LanguageStore
● Creación de ficheros de lenguaje 0,5h 27/04/2018
● Creación de los Stores [Implementación] 3,5h: ○ Geolocalización
● Realizar pruebas de Geolocalización [Pruebas] 0,5h 30/04/2018
● Creación de los Stores [Implementación] 3h: ○ Geolocalización
● Configuración de Google Maps para la geocodificación [Implementación] 0,5h ● Realizar pruebas de Geolocalización [Pruebas] 0,5h
01/05/2018
● Documentación 5h: ○ Metodología ○ Presupuesto ○ Planificación temporal ○ Diagrama de Gantt
● Creación de pantallas de Chat (Lista e individual) [Diseño] 2h 04/05/2018
● Implementación parcial de WebSockets en el cliente [Implementación] 2,5h
Página 82
● Pruebas con Postman y Smart WebSocket Client 2h 05/05/2018
● Implementación parcial de WebSockets en el cliente [Implementación] 1h ● Pruebas con Postman y Smart WebSocket Client 2h ● Creación de las pantallas 2h:
○ Perfil ○ Sobre la aplicación ○ Términos y condiciones
06/05/2018
● Crear pantallas relacionadas con la funcionalidad de Chat [Diseño]4h 07/05/2018
● Terminar sistema de WebSockets [Implementación] 1h ● Sistema de re-autenticación tras reabrir la aplicación [Implementación] 1h ● Pruebas con Postman y Smart WebSocket Client 2h
08/05/2018
● Implementación de notificaciones Push en el cliente [Implementación] 1h ● Guardado en base de datos local del token de dispositivo proporcionado por Firebase
[Implementación] 0,5h ● Pruebas de envío de servidor a cliente de notificaciones Push 2h
10/05/2018
● Cambio de librería de Geolocalización de Google Maps a una solución local mediante el uso de una base de datos precargada de www.GeoNames.com [Implementación] 5h
11/05/2018
● Documentación 4h: ○ Arquitectura de la aplicación ○ Modelado de datos provisional ○ Detallamiento de las rutas del API Rest
● Elección de tipografía 0,5h 13/05/2018
● Documentación 2h: ○ Análisis y diseño de la interfaz de usuario
15/05/2018
● Despliegue del servidor en un servidor virtual real 4h ● Pruebas con el servidor real 2h
Página 83
16/05/2018
● Documentación 4h: ○ Arquitectura de la aplicación ○ Modelado de datos provisional ○ Detallamiento de las rutas del API Rest
17/05/2018
● Perfeccionamiento del sistema en tiempo real (chat) [Implementación] 4h 18/05/2018
● Pruebas generales con sujetos reales [Pruebas] 6h ● Mejora del sistema de tiempo real de servidor. 0,5h
20/05/2018
● Paginación de las publicaciones [Implementación] 2h ● Paginación de los mensajes de chat [Implementación] 2h
21/05/2018
● Comienzo del sistema de búsqueda [Implementación] 2h ● Organización y formateo de código 0,5h ● Reducción de código duplicado 0,5h
22/05/2018
● Pasar validaciones del cliente al servidor 3h ● Verificar validaciones con Postman 2h
23/05/2018
● Mejora de la navegación de la aplicación 2h ● Pruebas generales de la aplicación en compilación release [Pruebas] 2h
24/05/2018
● Documentación 3h: ○ Casos de uso ○ Diagrama de navegación
25/05/2018
● Documentación 4h 26/05/2018
● Documentación 1h:
Página 84
○ Casos de uso ○ Diagrama de navegación
● Desarrollo del sistema de progreso de imagen de perfil [Implementación] 4h 27/05/2018
● Realización de pruebas de caja negra con Postman 5h 28/05/2018
● Documentación. Cambios generales, adicción de imágenes 5h 29/05/2018
● Actualización react-navigation y realizar los cambios necesarios [Implementación] 4h ● Documentación 0,5h
30/05/2018
● Documentación 3h ● Mejoras estéticas de la aplicación [Diseño] 2h
31/05/2018
● Documentación 3h: ○ Documento legal, términos y condiciones
● Retoques finales de documentación 2h
Página 85
Página 86