Habilitar a sincronização offline para seu aplicativo móvel Cordova

Visão geral

Este tutorial apresenta o recurso de sincronização offline dos Aplicativos Móveis do Azure para o Cordova. A sincronização offline permite que os usuários finais interajam com um aplicativo móvel, exibindo, adicionando ou modificando dados, mesmo quando não há nenhuma conexão de rede. As alterações são armazenadas em um banco de dados local. Quando o dispositivo estiver online novamente, essas alterações serão sincronizadas com o serviço remoto.

Este tutorial se baseia na solução de início rápido do Cordova para os Aplicativos Móveis criados quando você conclui o tutorial Início rápido do Apache Cordova. Neste tutorial, você atualizará a solução de início rápido para adicionar recursos offline dos Aplicativos Móveis do Azure. Também destacamos o código especificamente offline no aplicativo.

Para saber mais sobre o recurso de sincronização offline, confira o tópico Sincronização de dados offline nos Aplicativos Móveis do Azure. Para obter detalhes sobre o uso da API, consulte a documentação da API.

Adicionar a sincronização offline à solução de início rápido

O código da sincronização offline deve ser adicionado ao aplicativo. A sincronização offline requer o plug-in cordova-sqlite-storage, que é adicionado automaticamente ao seu aplicativo quando o plug-in dos Aplicativos Móveis do Azure está incluído no projeto. O projeto de Início Rápido inclui os dois plug-ins.

  1. No Gerenciador de Soluções do Visual Studio, abra o index.js e substitua o código a seguir

     var client,            // Connection to the Azure Mobile App backend
        todoItemTable;      // Reference to a table endpoint on backend
    

    por este código:

     var client,            // Connection to the Azure Mobile App backend
        todoItemTable,      // Reference to a table endpoint on backend
        syncContext;        // Reference to offline data sync context
    
  2. Em seguida, substitua o código a seguir:

     client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net');
    

    por este código:

     client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net');
     var store = new WindowsAzure.MobileServiceSqliteStore('store.db');
    
     store.defineTable({
       name: 'todoitem',
       columnDefinitions: {
           id: 'string',
           text: 'string',
           complete: 'boolean',
           version: 'string'
       }
     });
    
     // Get the sync context from the client
     syncContext = client.getSyncContext();
    

    As adições de código anteriores inicializam o armazenamento local e definem uma tabela local que corresponde aos valores da coluna usados no back-end do Azure. (Você não precisa incluir todos os valores de coluna neste código.) O version campo é mantido pelo back-end móvel e é usado para resolução de conflitos.

    Você obtém uma referência para o contexto de sincronização chamando getSyncContext. O contexto de sincronização ajuda a preservar relações da tabela controlando e enviando por push as alterações em todas as tabelas que um aplicativo cliente tenha modificado quando o .push() é chamado.

  3. Atualize a URL do aplicativo para a URL do Aplicativo Móvel.

  4. Em seguida, substitua este código:

     todoItemTable = client.getTable('todoitem'); // todoitem is the table name
    

    por este código:

     // Initialize the sync context with the store
     syncContext.initialize(store).then(function () {
    
     // Get the local table reference.
     todoItemTable = client.getSyncTable('todoitem');
    
     syncContext.pushHandler = {
         onConflict: function (pushError) {
             // Handle the conflict.
             console.log("Sync conflict! " + pushError.getError().message);
             // Update failed, revert to server's copy.
             pushError.cancelAndDiscard();
           },
           onError: function (pushError) {
               // Handle the error
               // In the simulated offline state, you get "Sync error! Unexpected connection failure."
               console.log("Sync error! " + pushError.getError().message);
           }
     };
    
     // Call a function to perform the actual sync
     syncBackend();
    
     // Refresh the todoItems
     refreshDisplay();
    
     // Wire up the UI Event Handler for the Add Item
     $('#add-item').submit(addItemHandler);
     $('#refresh').on('click', refreshDisplay);
    

    O código anterior inicializa o contexto de sincronização e, em seguida, chama getSyncTable (em vez de getTable) para obter uma referência para a tabela local.

    Esse código usa o banco de dados local para todas as operações da tabela para criar, ler, atualizar e excluir (CRUD).

    Este exemplo executa o tratamento de erros simples nos conflitos de sincronização. Um aplicativo real trataria os diversos erros, como condições de rede, conflitos do servidor e outros. Para obter exemplos de código, confira o exemplo de sincronização offline.

  5. Em seguida, adicione esta função para executar a sincronização real.

     function syncBackend() {
    
       // Sync local store to Azure table when app loads, or when login complete.
       syncContext.push().then(function () {
           // Push completed
    
       });
    
       // Pull items from the Azure table after syncing to Azure.
       syncContext.pull(new WindowsAzure.Query('todoitem'));
     }
    

    Você decide quando enviar as alterações por push para o back-end do Aplicativo Móvel chamando syncContext.push(). Por exemplo, você poderia chamar syncBackend em um manipulador de eventos ligado a um botão de sincronização.

Considerações sobre a sincronização offline

No exemplo, o método push de syncContext apenas é chamado na inicialização do aplicativo na função de callback do logon. Em um aplicativo real, você também poderia disparar manualmente essa funcionalidade de sincronização ou quando o estado da rede muda.

Quando um pull é executado em uma tabela que tenha atualizações locais pendentes controladas pelo contexto, essa operação de pull automaticamente dispara um envio por push. Durante a atualização, a adição e a conclusão de itens neste exemplo, você pode omitir a chamada push explícita, pois ela pode ser redundante.

No código fornecido, todos os registros na tabela remota todoItem são consultados, mas também é possível filtrar os registros passando uma id de consulta e uma consulta para push. Para obter mais informações, consulte a seção Sincronização Incremental na Sincronização de Dados Offline nos Aplicativos Móveis do Azure.

(Opcional) Desabilitar a autenticação

Se você não desejar configurar a autenticação antes da sincronização offline de teste, remova a marca de comentário da função de callback para logon, mas deixe o código dentro dessa função sem comentário. Após remover as marcas de comentário das linhas de logon, o código será:

  // Login to the service.
  // client.login('twitter')
  //    .then(function () {
    syncContext.initialize(store).then(function () {
      // Leave the rest of the code in this callback function  uncommented.
            ...
    });
  // }, handleError);

Agora, o aplicativo será sincronizado com o back-end do Azure quando você executar o aplicativo.

Execute o aplicativo cliente

Com a sincronização offline agora habilitada, você poderá executar o aplicativo cliente pelo menos uma vez em cada plataforma para preencher o banco de dados do repositório local. Posteriormente, simule um cenário offline e modificará os dados no armazenamento local enquanto o aplicativo estiver offline.

(Opcional) Testar o comportamento da sincronização

Nesta seção, você modificará o projeto do cliente para simular um cenário offline usando uma URL de aplicativo inválida para o back-end. Quando você adicionar ou alterar itens de dados, essas alterações são mantidas no repositório local, mas não são sincronizadas com o armazenamento de dados de back-end até que a conexão seja restabelecida.

  1. No Gerenciador de Soluções, abra o arquivo de projeto index.js e altere a URL do aplicativo para apontar para uma URL inválida, como o seguinte código:

     client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net-fail');
    
  2. Em index.html, atualize o elemento CSP <meta> com a mesma URL inválida.

     <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: http://yourmobileapp.azurewebsites.net-fail; style-src 'self'; media-src *">
    
  3. Compile e execute o aplicativo cliente, e observe que uma exceção é registrada no console quando o aplicativo tenta sincronizar com o back-end após o logon. Todos os novos itens adicionados existem apenas no repositório local até que possam ser enviados por push para o back-end móvel. O aplicativo cliente se comporta como se ele estivesse conectado ao back-end.

  4. Feche o aplicativo e reinicie-o para verificar se os novos itens que você criou persistem no armazenamento local.

  5. (Opcional) Use o Visual Studio para exibir a tabela de Banco de Dados SQL do Azure para ver se os dados no banco de dados do back-end não foram alterados.

    No Visual Studio, abra Gerenciador de Servidores. Navegue até o banco de dados nos Bancos de DadosAzure-SQL>. Clique com o botão direito do mouse em seu banco de dados e selecione Abrir no Pesquisador de Objetos do SQL Server. Agora você pode navegar até sua tabela de banco de dados SQL e seu conteúdo.

(Opcional) Testar a reconexão com seu back-end móvel

Nesta seção, reconecte o aplicativo ao back-end móvel, que simula o aplicativo voltando ao estado online. Quando você fizer logon, os dados serão sincronizados com o back-end móvel.

  1. Abra index.js novamente e restaure a URL do aplicativo.

  2. Reabra o index.html e corrija a URL do aplicativo no elemento CSP <meta> .

  3. Recompile e execute o aplicativo cliente. O aplicativo tenta sincronizar com o back-end do aplicativo móvel após fazer logon. Verifique se nenhuma exceção está registrada no console de depuração.

  4. (Opcional) Exiba os dados atualizados usando o Gerenciador de objetos do SQL Server ou uma ferramenta REST como o Fiddler. Observe que os dados foram sincronizados entre o banco de dados de back-end e o repositório local.

    Observe que os dados foram sincronizados entre o banco de dados e o armazenamento local e contém os itens que você adicionou enquanto seu aplicativo estava desconectado.

Recursos adicionais

Próximas etapas