Fala Devs, blz?? É comum no ciclo de vida de desenvolvimento de um aplicativo ele passar por um processo de testes de usuário antes de ser disponibilizado nas lojas e é comum que bugs sejam encontrados. Muitas vezes esses bugs podem não estar no aplicativo e sim na API que está integrada e para que nosso colega desenvolvedor backend consiga reproduzir o erro precisamos passar qual a requisição que estamos realizando e que ocorreu erro para simular o erro do lado do servidor.
Para isso, muitas vezes precisamos depurar o aplicativo e tentar reproduzir o erro que o usuário realizou para conseguir interceptar qual a requisição que está sendo enviada, um baita trabalhão!
Não seria ótimo assim que o usuário que está testando a aplicação assim que encontrasse o erro pudesse recuperar a requisição (como consegue no DevTools do Google Chrome) e ao relatar o problema já nos informasse qual foi a requisição?
Existe um package que acho essencial para qualquer projeto e que faz exatamente isso, o alice_lightweight (https://pub.dev/packages/alice_lightweight)
Após instalar o alice em seu projeto a primeira tarefa que temos que fazer é criar uma instancia do Alice em nosso projeto, no caso para conseguirmos injetar a dependência nas classes subsequentes (como estou fazendo no AppController)
Também vamos criar a instancia do HTTP Client de nossa preferência, no caso estou usando o DIO, e necessitamos adicionar o interceptador que o alice nos oferece interceptors já prontos dos principais HTTP Clients:
· Dio
· HttpClient do dart:io package
· Http do http/http package
· Chopper
· Generic HTTP cliente
No caso podemos adicionar uma condição parra adicionar o interceptor somente quando o aplicativo estiver para teste para que o aplicativo em produção não mostre esses logs.
Em nosso MaterialApp precisamos adicionar o navigatorKey do alice
Para abrir a tela de relatório basta na tela recuperarmos a instancia do Alice que configuramos no MaterialApp e chamar a função o showInspector().
O resultado será o seguinte
BONUS!!
Uma forma legal e bastante útil de apresentarmos esses relatórios e através de push notifications, ou seja, toda hora que o usuário fizer uma requisição na API iremos disparar um push notification para o dispositivo. Para isso utilizaremos o pacote flutter_local_notifications (flutter_local_notifications).
Leia a documentação e faça toda a configuração do Android e iOS é muito simples.
Em seguida iremos criar uma classe responsável por gerenciar os push notifications, chamaremos de LocalNotificationService.
Primeiro vamos criar o método de inicialização precisamos configurar tanto a inicialização do Android quanto do iOs.
Depois vamos montar o método responsável por disparar as notificações
E finalmente fazemos o método que irá abrir o relatório do alice quando o push notification for aberto.
import 'dart:math'; | |
import 'package:alice_lightweight/alice.dart'; | |
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; | |
class LocalNotificationService { | |
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); | |
final Alice alice; | |
LocalNotificationService({ | |
required this.alice, | |
}); | |
show({ | |
required String title, | |
required String body, | |
}) async { | |
const AndroidNotificationDetails androidPlatformChannelSpecifics = | |
AndroidNotificationDetails( | |
'localStorage_', | |
'localStorage__chanel', | |
); | |
const IOSNotificationDetails iOSPlatformChannelSpecifics = | |
IOSNotificationDetails(); | |
const NotificationDetails platformChannelSpecifics = NotificationDetails( | |
android: androidPlatformChannelSpecifics, | |
iOS: iOSPlatformChannelSpecifics, | |
); | |
await flutterLocalNotificationsPlugin.show( | |
Random().nextInt(10000), | |
title, | |
body, | |
platformChannelSpecifics, | |
); | |
} | |
Future<void> init() async { | |
const AndroidInitializationSettings initializationSettingsAndroid = | |
AndroidInitializationSettings('ic_launcher'); | |
IOSInitializationSettings initializationSettingsIOS = | |
IOSInitializationSettings( | |
requestSoundPermission: false, | |
requestBadgePermission: false, | |
requestAlertPermission: false, | |
onDidReceiveLocalNotification: onDidReceiveLocalNotification, | |
); | |
InitializationSettings initializationSettings = InitializationSettings( | |
android: initializationSettingsAndroid, | |
iOS: initializationSettingsIOS, | |
); | |
await flutterLocalNotificationsPlugin.initialize( | |
initializationSettings, | |
onSelectNotification: selectNotification, | |
); | |
} | |
Future selectNotification(String? payload) async { | |
//Handle notification tapped logic here | |
alice.showInspector(); | |
} | |
void onDidReceiveLocalNotification( | |
int id, String? title, String? body, String? payload) async {} | |
} |
Para finalizar no meu MaterialApp apenas preciso recuperar a instancia do LocalNotificationService e invocar o método de inicialização.
E voila! O resultado que teremos é a seguinte.
Legal ne? Isso facilitou bastante minha vida e aposto que irá ajudar bastante.
Entre em nosso discord para interagir com a comunidade: https://discord.com/invite/flutterbrasil
https://linktr.ee/flutterbrasil
Top comments (0)