O MAUI usa o SDK .NET, que tem como alvo o netstandard2.0 e é o mesmo pacote que uma aplicação WPF, WinForms, Avalonia ou de consola usaria; vê medir uma aplicação para saberes o que reporta. O que é específico do MAUI é onde o arrancas, onde pões a fila dele, e como os ecrãs ficam com nome.
O código-fonte, e uma aplicação de secretária de demonstração que se reporta a si mesma, estão em skomi-sdk-dotnet.
Um cliente, para toda a vida da aplicação
Regista-o no MauiProgram.cs para que a aplicação tenha exatamente um:
builder.Services.AddSingleton(_ => new SkomiClient(new SkomiOptions
{
AppId = Guid.Parse("your-app-id"), // de As minhas aplicações na Skomi
AppVersion = AppInfo.Current.VersionString,
StoragePath = FileSystem.Current.AppDataDirectory,
}));
O AppVersion assume por omissão a versão do assembly de entrada, que no MAUI não é a versão que entregaste a uma loja. O AppInfo.Current.VersionString é.
O StoragePath decide onde vive a fila para quando não há rede. O FileSystem.Current.AppDataDirectory é privado da aplicação em todos os alvos do MAUI e sobrevive a uma atualização, coisa que o caminho de origem dos dados locais da aplicação não faz de forma fiável em telemóveis.
⚠ Descarta-o ao desligar. Isso para o temporizador e faz uma última tentativa limitada de entrega; o que não for agora fica em disco e vai na corrida seguinte. Se o registaste como singleton, o contentor de injeção descarta-o por ti quando o anfitrião desliga, mas uma aplicação MAUI é muitas vezes morta em vez de desligada, que é a razão de a fila existir de todo.
Dá nome aos teus ecrãs
skomi.Screen("checkout/review", new Dictionary<string, object?> { ["tier"] = "gold" });
Não há recolha automática de nomes de página: a classe de uma página é como o teu código chama a um ecrã, não como lhe chamarias num relatório. O sítio natural no MAUI é um tratador único na navegação:
Shell.Current.Navigated += (_, e) =>
skomi.Screen(e.Current.Location.OriginalString.Trim('/'));
O que é um ponto de partida e não uma regra: as cadeias de rota só dão nomes legíveis se as tuas rotas forem legíveis.
Erros
try
{
await CheckoutAsync();
}
catch (Exception ex)
{
skomi.CaptureError(ex, fatal: false, screenName: "checkout/review");
ShowRetry();
}
As faltas são agrupadas por tipo em vez de por mensagem, porque uma mensagem transporta identificadores e valores que tornam única cada ocorrência.
⚠ Isto não é um relator de falhas. Grava as faltas que lhe entregas e as exceções geridas que consegue ver; uma falha nativa no Android ou no iOS leva o processo com ela antes de se conseguir escrever seja o que for. Fica com o relatório da própria loja, ou com o Crashlytics ou o Sentry, para essas; o que a Skomi acrescenta é uma taxa sem falhas ao lado dos números das tuas versões, e os erros que escolheste reportar.
Também não há envio de ficheiros de mapeamento, portanto uma pilha de uma versão minificada chega tal como foi lançada.
Nunca lança para dentro do teu código
Todos os métodos públicos engolem e reportam através do OnError, que é silencioso por omissão, o certo para uma aplicação entregue e o errado enquanto estás a integrar:
OnError = (ex, stage) => Debug.WriteLine($"Skomi {stage}: {ex}"),
À espera do consentimento
new SkomiOptions { AppId = id, Enabled = false }
Com Enabled = false não se grava nada e não se envia nada, portanto um cliente pode existir desde o arranque e só começar a recolher depois de alguém concordar.
Confirma que está a funcionar
Corre a aplicação, muda entre duas páginas, e olha para o teu painel. Se não chegar nada, define primeiro o OnError: um identificador de aplicação da aplicação errada e um cliente que nunca foi descartado são as duas causas habituais, e sem ele as duas são silenciosas.