Um dos recursos interessantes do Couchbase Lite que não tem sido muito apresentado é a capacidade de fazer replicação P2P entre dois dispositivos. O Couchbase Lite é empacotado com um componente extra chamado Couchbase Lite Listener, que permite que seu aplicativo aceite conexões HTTP de outros dispositivos que executam o Couchbase Lite e sincronize dados com eles.

Há alguns meses, Wayne Carter (arquiteto-chefe de dispositivos móveis) e Traun Leyden (engenheiro de Android) me ligaram e me venderam a ideia de criar um aplicativo simples de compartilhamento de fotos P2P que demonstrasse como é fácil desenvolver um aplicativo P2P usando o Couchbase Lite. Desde então, eu estava empenhado e passei alguns dias trabalhando nesse pequeno aplicativo de compartilhamento de fotos P2P para iOS chamado PhotoDrop. Nesta postagem do blog, mostrarei como usei o Couchbase Lite para desenvolver o aplicativo. Isso é o que você terá no final:

Visão geral

O PhotoDrop é um aplicativo de compartilhamento de fotos P2P semelhante ao recurso AirDrop do iOS que pode ser usado para enviar fotos entre dispositivos. Antes de entrar no código, gostaria de discutir brevemente as preocupações com P2P e as escolhas de design que fiz ao desenvolver o aplicativo.

Descoberta de pares pode ser feito de várias maneiras. No iOS, você pode usar o Bonjour Service para descobrir pares, mas isso pode ser um problema se mais tarde você quiser desenvolver o aplicativo em outras plataformas. No PhotoDrop, estou usando uma maneira mais simples e direta, usando um QRCode. Uso o QRCode para anunciar um URL de endpoint adhoc que um remetente pode escanear e enviar fotos.

Identidade de pares é um assunto relacionado à descoberta de pares. Normalmente, é difícil resolver a identificação de pares sem introduzir algumas etapas indesejadas no aplicativo, como registro de usuário, login de usuário e aprovação de pares. Ao usar um QRCode e exigir que as duas pessoas tenham uma interação direta e explícita para enviar e receber fotos, o problema é atenuado.

Autenticação é necessário para garantir que o controle de acesso, neste caso o acesso de gravação para enviar fotos para o banco de dados de outro par, seja concedido à pessoa certa. No PhotoDrop, estou usando o Basic Auth que o Couchbase Lite já suporta. Gero com segurança um nome de usuário e uma senha de uso único, os agrupo com o endpoint de URL e codifico todos eles no QRCode apresentado pelo receptor ao remetente. Depois que o remetente escaneia o QRCode, ele terá o nome de usuário e a senha para a autenticação básica.

Canais de comunicação seguros são necessários, especialmente para o envio de informações confidenciais. Não implementei comunicação segura neste aplicativo. No entanto, recentemente Jen Alfke adicionou suporte a TLS, incluindo uma API para gerar um certificado autoassinado em tempo real para o iOS Couchbase Lite Listener. Como todo o trabalho árduo já foi feito, você pode adicionar suporte para isso com bastante facilidade.

Afinal de contas, o fluxo atual do PhotoDrop é bastante simples. Você seleciona as fotos que deseja compartilhar com seu amigo e abre o scanner QRCode para digitalizar o endpoint de destino para o qual as fotos selecionadas serão enviadas. Do outro lado, seu amigo abre o aplicativo, mostra o QRCode e espera que você escaneie e envie as fotos. A próxima seção fornecerá todos os detalhes de implementação do aplicativo.

Seleção de fotos

O PhotoDrop usa ALAssetsLibrary para acessar as fotos no álbum Camera Roll em um dispositivo iOS porque o UIImagePickerViewController não oferece suporte à seleção de várias fotos.

As fotos são exibidas em um UICollectionViewController. Um UICollectionViewCell personalizado simples chamado PhotoViewCell é criado para exibir uma miniatura da foto e uma caixa de seleção que indica o status selecionado da foto.

Envio de fotos

Quando as fotos selecionadas estiverem prontas para serem enviadas e o botão de envio for tocado, o SendViewController será apresentado com as fotos selecionadas.

Depois que o SendViewController é apresentado, nos deparamos com a função viewDidLoad(), na qual obtemos um objeto de banco de dados vazio chamado "db" da classe DatabaseUtil. O motivo pelo qual obtemos um banco de dados novo é para garantir que não haja documentos pendentes de uma sessão de compartilhamento anterior.
A função getEmptyDatabase() da classe DatabaseUtil retorna um banco de dados vazio com o nome fornecido, excluindo o banco de dados, se ele existir, e recriando um novo.

Depois que o SendViewController for apresentado, estaremos na função viewDidAppear(animated:Bool). Na função viewDidAppear, iniciamos a sessão de captura de QRCode da AVFoundation para apresentar o scanner de QRCode.

Quando um QRCode é capturado, extraímos o URL do ponto de extremidade, que é o URL remoto para o qual enviaremos as fotos. O código principal para criar e enviar documentos com fotos começa e termina na função replicate(url: NSURL), que tem cerca de 50 linhas de código.

O código começa com o looping de cada foto na matriz sharedAssets. Para cada foto, obtemos uma representação binária e a anexamos a um documento vazio do Couchbase Lite.

Depois que terminamos de criar os documentos com foto, enviamos esses documentos para o outro dispositivo. Para fazer isso, criamos um replicador push e definimos os IDs dos documentos que gostaríamos de replicar. Em geral, a configuração dos IDs dos documentos para o replicador é opcional. Se os ids não forem fornecidos, o replicador apenas replicará todos os documentos no banco de dados.

Antes de iniciarmos o replicador, configuramos um observador de notificação para observar o status da replicação, de modo que possamos exibir o status da replicação adequadamente quando ela estiver em andamento.

Recebimento de fotos

O recebimento de fotos é feito no ReceiveViewController, que é apresentado na tela ViewController quando um usuário toca no botão Receive. Quando o ReceiveViewController é apresentado, obtemos um banco de dados novo chamado "db" no método viewDidLoad(). Na função viewDidAppear(animated: Bool), chamamos startListener() para criar e iniciar um objeto CBLListener. O CBLListener é um servidor HTTP leve incorporado que escuta as solicitações HTTP e as encaminha para os manipuladores apropriados para executar as operações de replicação. Depois que o ouvinte é iniciado, podemos obter o URL do ouvinte e apresentar um QRCode que codifica o URL. Como bônus, o iOS CoreImage oferece suporte a um filtro QRCode, portanto, gerar uma imagem QRCode é muito fácil :)

Quando configuramos o ouvinte em startListener(), ativamos a autenticação básica com o par de nome de usuário/senha gerado. O par nome de usuário/senha gerado serve como um par de uso único que fornece uma solução segura (suficiente) para evitar que usuários não autorizados enviem imagens para o receptor. Para gerar o nome de usuário e a senha, usamos a API do iOS Randomization Services (SecRandomCopyBytes) que gera valores aleatórios criptograficamente seguros.

No final da função startListener(), a função startObserveDatabaseChange() é chamada para observar quaisquer alterações que ocorram no banco de dados por meio de notificações denominadas kCBLDatabaseChangeNotification. Agora podemos observar quando os documentos fotográficos do outro dispositivo são replicados e salvar as fotos no rolo da câmera do dispositivo.

A função para salvar uma foto no rolo da câmera do dispositivo está abaixo. A função simplesmente obtém a imagem do anexo do documento, cria uma CGImage e a salva no rolo da câmera por meio da função writeImageDataToSavedPhotosAlbum() da ALAssetsLibrary. Depois de salvar uma foto, exibimos uma miniatura na tela.

Concluindo

Há muitas maneiras de desenvolver o aplicativo PhotoDrop, e usar o Couchbase Lite talvez seja uma das mais fáceis. O código principal para enviar e receber fotos tem apenas 100 linhas de código e não contém nenhuma linha de código diretamente envolvida na comunicação de rede. Espero que esta postagem do blog e o próprio aplicativo PhotoDrop lhe dêem alguma inspiração e ideias para usar o Couchbase Lite em aplicativos P2P. Clone o aplicativo Repositório do PhotoDrop no GitHubSe você quiser, brinque com ele e me diga o que achou!

Autor

Postado por Pasin Suriyentrakorn, engenheiro de software sênior, Couchbase

Pasin Suriyentrakorn é engenheiro de software sênior da Couchbase para o Couchbase Mobile. Antes disso, foi engenheiro da Oracle, onde liderou o desenvolvimento da estrutura de renderização da interface de usuário móvel para o aplicativo Oracle Sales Cloud iOS e Android.

10 Comentários

  1. Obrigado, ótima postagem! É possível sincronizar réplicas em vários dispositivos usando bluetooth, por exemplo, usando a estrutura de conectividade Multipeer (embora com alguns problemas de confiabilidade) ou algo semelhante? De modo que não precisemos mais de wifi~

    1. Pasin Suriyentrakorn fevereiro 17, 2015 em 6:55 pm

      Podemos fazer a replicação P2P por Bluetooth usando o Bonjour. A estrutura do Multipeer Connectivity é uma estrutura criada com base no Bonjour, e poderíamos reconstruir o aplicativo usando-a. O único problema é que tanto o Bonjour quanto o Multipeer Connectivity não são multiplataforma.

      1. Como você obteria um URL na estrutura de conectividade do Multipeer? Pelo que entendi, você só pode obter MCPeerID(displayName myDisplayName: String)? que não pode ser usado no CBLListener? Gostaria de saber como você faria para criar um aplicativo de replicação usando a estrutura Multipeer Connectivity do iOS.

  2. Gostaria muito de ver uma implementação disso no Android.
    Além disso, você fez algum teste de capacidade?

    1. Pasin Suriyentrakorn fevereiro 17, 2015 em 7:52 pm

      Tenho um plano para portar o aplicativo para a plataforma Android, mas agora estou discutindo qual deles devo fazer primeiro, entre a plataforma Android ou Xamarin. Ainda não fiz nenhum teste formal de desempenho ou criação de perfil. Em geral, o aplicativo parece funcionar muito bem para meus usos normais, por exemplo, enviar mais de 10 fotos brutas em um tempo razoável.

      1. Você chegou a fazer isso funcionar no Android/Xamarin? Estou interessado no couchbase para meu aplicativo de tablet Android Xamarin, mas ele precisa desse recurso.

        1. James Nocentini junho 9, 2015 em 7:03 pm

          Olá, Jeremy, temos uma versão do PhotoDrop para Android aqui https://github.com/couchbasela….

          1. Olá, @James, o link não está funcionando. Você poderia compartilhar um link atualizado?

  3. Eu adoraria ver isso funcionando com o PhoneGap/Cordova também. Você sabe de mais alguém que já tenha tentado? Planeja testá-lo após a demonstração do Android ou do Xamarin?

    1. Pasin Suriyentrakorn junho 9, 2015 em 5:37 pm

      Acho que ninguém trabalhou na versão PhoneGap/Cordova. Temos um plano para fazer a versão Xamarin, mas atualmente os componentes P2P na plataforma CBL Xamarin ainda estão em andamento. Você pode perguntar sobre o status da replicação P2P do CBL Xamarin no fórum (https://forums.couchbase.com/c.... O @borrrden (Jim Borden) poderia dar algumas dicas sobre isso.

Deixar uma resposta