Crear una aplicación para compartir fotos entre iguales con Couchbase Mobile

Una de las características interesantes de Couchbase Lite que no se ha presentado mucho es la capacidad de hacer la replicación P2P entre dos dispositivos. Couchbase Lite viene empaquetado con un componente extra llamado Couchbase Lite Listener que permite a tu aplicación aceptar conexiones HTTP desde otros dispositivos que ejecuten Couchbase Lite y sincronizar datos con ellos.

Hace un par de meses, Wayne Carter (Arquitecto Jefe de Móviles) y Traun Leyden (ingeniero de Android) me llamaron por Skype y me vendieron la idea de crear una sencilla aplicación P2P para compartir fotos que pudiera demostrar lo fácil que es desarrollar una aplicación P2P usando Couchbase Lite. Me comprometí desde entonces y pasé un par de días trabajando en esta pequeña aplicación P2P iOS para compartir fotos llamada PhotoDrop. En esta entrada del blog, te mostraré cómo utilicé Couchbase Lite para desarrollar la aplicación. Esto es lo que obtendrás al final:

Visión general

PhotoDrop es una aplicación P2P para compartir fotos similar a la función AirDrop de iOS que puedes utilizar para enviar fotos entre dispositivos. Antes de entrar en el código, me gustaría discutir brevemente las preocupaciones P2P y las opciones de diseño que hice al desarrollar la aplicación.

Descubrimiento entre iguales se puede hacer de varias maneras. En iOS, puedes usar el Servicio Bonjour para descubrir pares pero esto podría ser un problema si más tarde quieres desarrollar la aplicación en otras plataformas. En PhotoDrop, estoy usando una forma más simple y directa usando un QRCode. Utilizo el QRCode para anunciar una URL de punto final adhoc que un remitente puede escanear y enviar fotos.

Identidad entre iguales es un tema relacionado con el Peer Discovery. La identificación de pares suele ser difícil de resolver sin introducir algunos pasos no deseados en la aplicación, como el registro de usuarios, el inicio de sesión de usuarios y la aprobación de pares. Utilizando un QRCode, y requiriendo que las dos personas tengan una interacción explícita directa para enviar y recibir fotos, se mitiga el problema.

Autenticación es necesario para asegurar que el control de acceso, en este caso el acceso de escritura para insertar fotos en la base de datos de otro par, se concede a la persona adecuada. En PhotoDrop, estoy usando el Basic Auth que Couchbase Lite ya soporta. Genero de forma segura un nombre de usuario y una contraseña de un solo uso, los junto con el endpoint URL y los codifico todos en el QRCode presentado por el receptor al emisor. Una vez que el remitente escanea el QRCode, el remitente tendrá el nombre de usuario y la contraseña para la autenticación básica.

Canales de comunicación seguros especialmente para enviar información sensible. No implementé la comunicación segura en esta aplicación. Sin embargo, recientemente Jen Alfke añadió soporte TLS incluyendo una API para generar un certificado autofirmado sobre la marcha al iOS Couchbase Lite Listener. Como todo el trabajo duro ya está hecho, puedes añadir soporte para esto fácilmente.

Después de todo, el flujo actual de PhotoDrop es bastante sencillo. Seleccionas las fotos que quieres compartir con tu amigo y abres el escáner QRCode para escanear el endpoint de destino al que se enviarán las fotos seleccionadas. Por otro lado, tu amigo abre la aplicación, muestra el QRCode y espera a que escanees y envíes las fotos. La siguiente sección proporcionará todos los detalles de implementación de la aplicación.

Selección de fotos

PhotoDrop utiliza ALAssetsLibrary para acceder a las fotos en el álbum Camera Roll en un dispositivo iOS porque el UIImagePickerViewController que no soporta la selección múltiple de fotos.

Las fotos se muestran en un UICollectionViewController. Se crea una sencilla UICollectionViewCell personalizada denominada PhotoViewCell para mostrar una miniatura de la foto y una casilla de verificación que indica el estado seleccionado de la foto.

Envío de fotos

Cuando las fotos seleccionadas estén listas para enviar y se pulse el botón de envío, se presentará el SendViewController con las fotos seleccionadas.

Una vez presentado el SendViewController, nos encontramos en la función viewDidLoad() en la que obtenemos un objeto de base de datos vacío llamado "db" de la clase DatabaseUtil. La razón por la que obtenemos una base de datos nueva es para asegurarnos de que no hay documentos pendientes de una sesión de compartición anterior.
La función getEmptyDatabase() de la clase DatabaseUtil devuelve una base de datos vacía con el nombre dado, borrando la base de datos si existe y volviendo a crear una nueva.

Una vez presentado el SendViewController, estaremos en la función viewDidAppear(animated:Bool). En la función viewDidAppear, iniciamos la sesión de captura QRCode de AVFoundation para presentar el escáner QRCode.

Cuando se captura un QRCode, extraemos la URL del endpoint que es la URL remota a la que enviaremos las fotos. El código central para crear y enviar documentos de fotos comienza y termina en la función replicate(url: NSURL) que tiene unas 50 líneas de código.

El código comienza con un bucle a través de cada foto en la matriz sharedAssets. Para cada foto, obtenemos una representación binaria y la adjuntamos a un documento vacío de Couchbase Lite.

Cuando terminamos de crear los documentos fotográficos, enviamos esos documentos al otro dispositivo. Para ello, creamos un replicador push y establecemos los identificadores de los documentos que queremos replicar. En general, establecer los ids de los documentos para el replicador es opcional. Si no se especifica, el replicador replicará todos los documentos de la base de datos.

Antes de iniciar el replicador, configuramos un observador de notificaciones para observar el estado de replicación, de forma que podamos mostrar el estado de replicación de forma adecuada cuando la replicación esté en curso.

Recepción de fotos

La recepción de fotos se realiza en ReceiveViewController que se presenta desde la pantalla ViewController cuando un usuario toca el botón Receive. Cuando se presenta el ReceiveViewController, obtenemos una base de datos fresca llamada "db" en el método viewDidLoad(). En la función viewDidAppear(animated: Bool), llamamos a startListener() para crear e iniciar un objeto CBLListener. El CBLListener es un servidor HTTP ligero embebido que escucha las peticiones HTTP y enruta esas peticiones a los manejadores apropiados para realizar las operaciones de replicación. Una vez iniciado el listener, podemos obtener la URL del listener y presentar un QRCode codificando la URL. Como bonus, iOS CoreImage soporta un filtro QRCode por lo que generar una imagen QRCode es realmente fácil :)

Cuando configuramos el receptor en startListener(), habilitamos la autenticación básica con el par usuario/contraseña generado. El par nombre de usuario/contraseña generado sirve como un par de un solo uso que proporciona una solución segura (suficiente) para evitar que usuarios no autorizados envíen imágenes al receptor. Para generar el nombre de usuario y la contraseña, utilizamos la API de servicios de aleatorización de iOS (SecRandomCopyBytes) que genera valores aleatorios criptográficamente seguros.

Al final de la función startListener(), se llama a la función startObserveDatabaseChange() para observar cualquier cambio que se produzca en la base de datos a través de las notificaciones denominadas kCBLDatabaseChangeNotification. Ahora podemos observar cuándo se replican los documentos fotográficos del otro dispositivo y guardar las fotos en el rollo de la cámara del dispositivo.

La función para guardar una foto en el rollo de la cámara del dispositivo es la siguiente. La función simplemente obtiene la imagen del documento adjunto, crea una CGImage y la guarda en el carrete mediante la función writeImageDataToSavedPhotosAlbum() de la ALAssetsLibrary. Después de guardar una foto, mostramos una miniatura en la pantalla.

Conclusión

Hay muchas maneras de desarrollar la aplicación PhotoDrop, y el uso de Couchbase Lite es quizás una de las más fáciles. El código central para enviar y recibir fotos es de apenas 100 líneas de código y contiene cero líneas de código directamente involucradas en la comunicación de red. Espero que esta entrada del blog y la propia aplicación PhotoDrop te den algo de inspiración e ideas para usar Couchbase Lite para aplicaciones P2P. Clona el Repo GitHub de PhotoDropJuega con él y cuéntame qué te parece.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Pasin Suriyentrakorn, Ingeniero Superior de Software, Couchbase

Pasin Suriyentrakorn es Ingeniero de Software Senior en Couchbase para Couchbase Mobile. Anteriormente, fue ingeniero en Oracle, donde dirigió el desarrollo del marco de renderización de la interfaz de usuario móvil para la aplicación Oracle Sales Cloud iOS y Android.

10 Comentarios

  1. ¡Gracias, gran post! ¿Es posible sincronizar réplicas en múltiples dispositivos usando bluetooth, por ejemplo usando Multipeer Connectivity framework(aunque con algunos problemas de fiabilidad) o similar? Tal que no necesitamos wifi más~

    1. Pasin Suriyentrakorn febrero 17, 2015 a 6:55 pm

      Podríamos hacer replicación P2P sobre bluetooth usando Bonjour. Multipeer Connectivity framework es un framework construido sobre Bonjour, y podríamos reconstruir la aplicación usándolo. Lo único es que tanto Bonjour como Multipeer Connectivity no son multiplataforma.

      1. ¿Cómo se obtiene una URL en Multipeer Connectivity framework? Según tengo entendido, sólo se puede obtener MCPeerID(displayName myDisplayName: String)? que no se puede utilizar en CBLListener? Me gustaría saber cómo se puede crear una aplicación de replicación utilizando el marco de conectividad Multipeer para iOS.

  2. Me encantaría ver una implementación de esto en Android.
    Además, ¿ha realizado alguna prueba de capacidad?

    1. Pasin Suriyentrakorn febrero 17, 2015 a 7:52 pm

      Tengo un plan para portar la aplicación a la plataforma Android, pero ahora estoy debatiendo cuál debo hacer primero entre Android o la plataforma Xamarin. No he hecho ninguna prueba formal de rendimiento o perfiles. En general, la aplicación parece funcionar bastante bien para mis usos normales, por ejemplo, el envío de más de 10 fotos sin procesar en un tiempo razonable.

      1. ¿Has conseguido que esto funcione en Android/Xamarin? Estoy interesado en couchbase para mi aplicación de tableta Android Xamarin pero necesita esta capacidad.

        1. James Nocentini junio 9, 2015 a 7:03 pm

          Hola Jeremy, tenemos una versión de PhotoDrop para Android aquí https://github.com/couchbasela….

          1. Hola @James el enlace no funciona puede usted por favor compartir y enlace actualizado.

  3. Me encantaría que esto funcionara también con PhoneGap/Cordova. ¿Conoces a alguien que lo haya probado ya? ¿Planeas probarlo después de la demo de Android o Xamarin?

    1. Pasin Suriyentrakorn junio 9, 2015 a 5:37 pm

      No creo que nadie haya trabajado en la versión PhoneGap/Cordova. Tenemos un plan para hacer la versión Xamarin, pero actualmente los componentes P2P en la plataforma CBL Xamarin está todavía en curso. Usted puede preguntar el estado de la replicación CBL Xamarin P2P en el foro (https://forums.couchbase.com/c.... @borrrden (Jim Borden) podría dar alguna idea al respecto.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.