Offline First no Flutter utilizando o DIO e Hive
Published: 2024-05-01 01:40:19

Quando desenvolvemos um aplicativo é muito comum termos dependência de dados que vem da internet, entretanto garantir que o usuário esteja 100% do tempo conectado á rede mundial de computadoress é uma tarefa impossível.

Com este problema em vista várias empresas adotam o conceito do Offline First, para garantir que algumas funcionalidades permaneçam funcionando mesmo que o usuário esteja desconectado a uma rede de internet.

O offline first trabalha com o conceito de local storage, que basicamente iremos armazenar informações que virão da internet (uma requisição da api) para quando o dispositivo do usuário estiver desconectado (ou até mesmo para não precisar fazer várias requisições desnecessárias) ele consiga utilizar algumas funções.

Para este artigo utilizaremos o Dio como cliente HTTP e o hive como banco de dados local, também precisaremos do build_runner e do hive_generator

{% gist https://gist.github.com/toshiossada/2473514cddabc06c08363d0665066cab file=pubspec.yaml %}

Primeiramente vamos construir o modelo que iremos salvar nossos dados offline (cache) , nele iremos precisar de um campo identificador, um para a data de atualização e um campo que irá conter o Map do resultado da API.
{% gist https://gist.github.com/toshiossada/d959c62f9506b626bd1108587e4d530d file=cache_model.dart %}

![](https://cdn-images-1.medium.com/max/800/1*Tvkn6GImmdF2l1LQe0J19w.png)

Será necessário executar o build_runner

> flutter pub run build_runner build

Nesse momento podemos criar a classe que ficará responsável por gerenciar este banco de dados local, chamaremos de cache_adapter. Nele teremos um método para recuperar o dado salvo em um determinado id, e outro para inserir/atualizar o valor armazenado

{% gist https://gist.github.com/toshiossada/67a01b2afa370dd5ffd2789779175033 file=cache_adapter.dart %}

Podemos melhorar este código e fazer a segregação por interface
{% gist https://gist.github.com/toshiossada/94be9560c7b2fad6935631c87a55d982 file=cache_adapter.dart %}

{% gist https://gist.github.com/toshiossada/c94334998c56207875b5d91946ddeff9 file=cache_model.dart %}
{% gist https://gist.github.com/toshiossada/7f575976544893ca5b55b314d5b2a9cb file=cache_hive.dart %}
{% gist https://gist.github.com/toshiossada/8d8e6cb906d2c0dba2ad0207e3849077 file=cache_model_database.dart %}

![](https://cdn-images-1.medium.com/max/800/1*nvBD3Cm6iCHerC5SovxIUw.png)

Agora vamos fazer um simples caso de uso que irá verificar se o dispositivo está conectado a internet.

{% gist https://gist.github.com/toshiossada/1428758852f4f737a9808e07baf38dab file=check_internet.dart %}

Agora no Dio precisamos criar um Interceptador pois iremos interceptar o métodos onRequest e onResponse. Neles vamos receber via injeção de dependências pelo construtor tanto a classe que irá gerenciar o cache, quanto o caso de uso que irá verificar a conectividade

Se não faz ideia do que são interceptadores do DIO tem um artigo bem legal que escrevi a um tempo explicando-os [https://toshiossada.medium.com/consumindo-api-utilizando-o-dio-9ec72aeceeaa](https://toshiossada.medium.com/consumindo-api-utilizando-o-dio-9ec72aeceeaa)

{% gist https://gist.github.com/toshiossada/5d86a1f57783b077fdd00200ad6bc269 file=interceptor.dart %}


Agora no método onResponse vamos armazenar o resultado da consulta quando fizermos uma requisição GET e colocaremos um tempo de validade de cinco minutos no cache armazenado. Note que como id usaremos o path da requisição GET, pois desta maneira toda vez que ele fizer requisição para o mesmo endpoint iremos atualizar o valor para o mais atual.

{% gist https://gist.github.com/toshiossada/465f58b1b9da1ce405d30f51ab8f2c8c file=onResponse.dart %}

No Método onRequest chamamos o caso de uso para verificar a conectividade do dispositivo e caso não esteja conectado iremos recuperar o valor armazenado para aquela URL.

{% gist https://gist.github.com/toshiossada/08be47dc552f79d93a80fb225f725640 file=onRequest.dart %}

Desta forma mesmo com o dispositivo offline conseguiremos continuar fazendo a busca

![](https://cdn-images-1.medium.com/max/800/1*Mthm8FaJ9uYq1wZa9kfefw.gif)

Legal né? Agora você pode utilizar esta ideia e evoluir seus aplicativo para funcionar de forma offline

Acesse o projeto de exemplo
https://github.com/toshiossada/termo_hack

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obcg0d2y00yddve9quky.png)


Entre em nosso discord para interagir com a comunidade: https://discord.com/invite/flutterbrasil
https://linktr.ee/flutterbrasil