
Brinquedo novo
Continuamos a nos familiarizar com o novo material da Apple apresentado na WWDC. Desta vez, considere o
MetricKit , uma estrutura completamente nova que serve como uma ferramenta para monitorar o desempenho do aplicativo.
Todo mundo sabe que é fácil medir o desempenho do aplicativo durante o desenvolvimento. O Xcode mostra a quantidade de RAM usada e a carga do processador, você pode conectar o Instruments a um simulador ou dispositivo em teste e até escrever suas próprias ferramentas (para obter mais detalhes, consulte nossos artigos sobre pacotes de ferramentas personalizados:
parte 1 /
parte 2 ). Apenas compreender a importância do ajuste de desempenho não permite medir quase tudo o que o aplicativo faz. Mas as coisas ficam mais complicadas quando falamos sobre a AppStore, se o aplicativo desenvolvido for destinado a usuários reais. Não importa o quão cuidadosamente você teste seu aplicativo, em condições reais sempre haverá muitas surpresas que afetarão o desempenho e a experiência do usuário. Obviamente, existem muitas ferramentas para coletar vários parâmetros, mas a maioria deles é limitada pelo
SDK do
iOS , além do impacto do monitoramento real no comportamento do aplicativo.
Este ano, a Apple decidiu preencher essa lacuna e forneceu aos desenvolvedores uma ferramenta que os ajuda a coletar e analisar as métricas de desempenho de aplicativos em um ambiente do mundo real. Eles anunciaram o
MetricKit (uma estrutura que fornece acesso às opções fornecidas pelo sistema operacional) de uma guia separada no organizador do Xcode 11, onde é possível encontrar as configurações do aplicativo. Pausaremos no MetricKit, porque a exibição dos parâmetros no Xcode funcionará apenas com aplicativos que já foram publicados na AppStore.

MXMetricManager
A arquitetura da estrutura é bastante simples e direta. A parte central é ocupada pela classe
MXMetricManager , que é uma estrutura de elemento único que fornece ao desenvolvedor um grande conjunto de APIs de estrutura.
Em geral, o fluxo de trabalho consiste em 3 etapas principais:
- Você inicializa o MXMetricMnager e atribui um observador para ele.
- Se desejar, você pode implementar suas próprias métricas em seu aplicativo usando a API do Signpost
- E, finalmente, agora estamos lidando com os dados recebidos no método didReceivePayloads, ou seja, envie-os ao seu back-end para análises adicionais.
Os parâmetros vêm como uma matriz de instâncias do
MXMetricPayload . A carga útil encapsula conjuntos de metadados e registros de data e hora. A carga útil métrica é um invólucro simples para subclassificar o
MXMetric . Para cada tipo de parâmetro, é separado.
Os tipos de métricas são muito bem documentados pela Apple, portanto, não vamos insistir nisso por muito tempo. No entanto, você deve parar para notar uma coisa interessante - o MXMetric fornece uma API aberta para serializá-la no NSDictionary ou JSON, o que, na minha opinião, é um pouco incomum.
Componentes internos do MetricKit.
Lá fora, o MetricKit parece bem simples. Mas é sempre interessante ver como tudo funciona de dentro para fora. A imersão em algo mais profundo é sempre uma intriga, se você estiver enfrentando uma tarefa específica. Por isso, decidi que queria passar parâmetros com as tags MetricKit e solicitá-los a fornecer-me métricas atualizadas a qualquer momento. Obviamente, você pode usar `
Debug -> Simulate Payloads do MetricKit` no Xcode, mas o id não permite que você exiba seus próprios dados. É verdade que essa equipe não é muito útil, mas fornece orientação em sua pesquisa e parece muito engraçada;)
Para iniciar a tarefa, obviamente precisamos do próprio MetricKit. Você pode pensar que é fácil obter um arquivo binário para a estrutura, porque o Xcode o mostra na lista de estruturas assim que você o adiciona na caixa de diálogo "vincular arquivo binário às bibliotecas". Este é um pensamento muito otimista. Porque se você abrir o
MetricKit.framework , verá o arquivo
MetricKit.tbd . Seu tamanho é de apenas
4kb . Obviamente, não é isso que estamos procurando.
Então, o que realmente está acontecendo aqui?
TBD significa "stub do dylib baseado em texto" e é na verdade um arquivo YAML com uma descrição do dylib que exporta caracteres e um caminho para o binário do dylib. Vincular a arquivos tbd reduz o tamanho do binário. Posteriormente, em tempo de execução, o binário dylib real será baixado do sistema operacional no caminho especificado no arquivo tbd. É assim que o arquivo se parece quando você o abre no Xcode:

Usando o caminho do arquivo tbd, você pode facilmente obter o binário MetricKit para pesquisas adicionais, mas existe um método ainda mais simples.
Nosso aplicativo binário contém o caminho para cada biblioteca vinculada dinamicamente na seção de cabeçalho do Mach-O. Essas informações são facilmente recuperadas usando a ferramenta usando o sinalizador -l.
Aqui está a saída do projeto de teste que eu criei:
→ otool -l ./Metrics | grep -i metrickit name /System/Library/Frameworks/MetricKit.framework/MetricKit (offset 24)
Você pode ver o mesmo caminho que vimos anteriormente no arquivo tbd. Tendo um arquivo de estrutura binária, você pode dar uma olhada nos elementos internos. Para isso, eu costumo usar o
Hopper Disassemble . É uma ferramenta fácil de usar, mas muito poderosa para um estudo cuidadoso de arquivos binários.
Assim que o arquivo binário do MetricKit for aberto, vá para a guia 'Proc'. e expanda a lista "Tags". Aqui você pode ver todos os caracteres exportados. Selecionando um deles (por exemplo, MXMetricManager), veremos todos os seus métodos e, após a seleção de um método, veremos seu conteúdo no lado direito:

Ao visualizar a lista de métodos MXMetricManager [
https://gist.github.com/deszip/88a258ae21d33dc75d7cbac9569c6ec1 ], é muito fácil observar o método _checkAndDeliverMetricReports. Parece ser o que precisa ser chamado para que o MetricKit entregue atualizações aos assinantes.
Infelizmente, uma tentativa de ligar para ele não levou a uma ligação para o assinante, o que provavelmente significa que esses parâmetros não serão entregues. Considerando a implementação do método, notamos algumas coisas interessantes: enumera o conteúdo do diretório / Library / Caches / MetricKit / Reports.
Ele então tenta descompactar a instância MXMetricPayload para cada item no disco. E, finalmente, itera os assinantes registrados e chama o método didReceive com uma lista de dados.
O problema provavelmente é que não há dados em
/ Library / Caches / MetricKit / Reports , mas sabemos que precisamos de algumas instâncias arquivadas do MXMetricPayload. Então, vamos criá-los e colocá-los em disco antes de chamar '
_checkAndDeliverMetricReports '. Novamente, o plano é criar uma instância do MXMetricPayload, criar e adicionar qualquer tipo de MXMetric a ele e arquivar a instância de dados no disco. Afinal, chame o método '
_checkAndDeliverMetricReports ', isso deve levar a chamar nosso assinante com stub como argumento.
Examinando os documentos da Apple sobre carga útil e métricas, você pode perceber que eles não possuem inicializadores públicos, e a maioria das propriedades é somente leitura. Então, como é possível instanciar uma classe?
Volte ao Hopper novamente para ver uma lista dos métodos
MXMetricPayload :

Aqui você pode ver seus inicializadores e métodos para atribuir parâmetros. É fácil chamar métodos privados usando a classe
NSInvocation e o método 'performSelector' devido à natureza dinâmica do Objective-C.
Como exemplo, criaremos métricas para a CPU e as adicionaremos à carga útil. Usando este link, você pode encontrar o fragmento de código completo: [
https://gist.github.com/deszip/a0cf877b07cc2877129e0aaef2fed1e4 ].
E, finalmente, arquivamos tudo o que criamos e
gravamos os dados no
diretório / Library / Caches / MetricKit / Reports .
Agora é hora de chamar o método '
_checkAndDeliverMetricReports ', que deve levar a uma chamada para o assinante. Desta vez, passamos os dados com carga útil stubbed como argumento como argumento.
De onde vêm as métricas
A obtenção de relatórios é muito fácil de implementar por meio do
MetricKit , mas você provavelmente está interessado em aprender como os relatórios aparecem no diretório
app / Library . Aqui está como.
Cavando dentro do binário MetricKit, notei este método: '_createXPCConnection'. A verificação de sua implementação esclarece a situação - ele cria uma NSXPCConnection para serviço com o nome
com.apple.metrickit.xpc e duas interfaces
MXXPCServer e
MXXPCClient para os lados do cliente e do servidor. Se você olhar para a descrição do protocolo:

Conclusão
MetricKit é uma ferramenta única e indispensável para cuidar do desempenho de sua aplicação em condições reais de produção.
Infelizmente, atualmente não é possível dar uma olhada na interface do usuário 'Metric' no Xcode, exceto no que foi mostrado durante uma demonstração em uma sessão da WWDC.

Pode ser uma ferramenta inestimável para levar a experiência do usuário ao próximo nível, eliminando problemas de desempenho no seu código.
Uma desvantagem que vejo agora nesta ferramenta é a falta de detalhes para cada tipo: apenas a separação é a versão do aplicativo e você não pode ver nenhuma métrica para um grupo específico de dispositivos / versões / regiões do SO, etc.
Mas, é claro, sempre há a oportunidade de enviar dados para você mesmo para processamento adicional, juntamente com informações importantes que você precisa. Você pode anexá-lo a tarefas no seu rastreador de bugs e muito mais. No
AppSpector, nossa equipe está trabalhando para expandir a funcionalidade das ferramentas de monitoramento de desempenho usando dados obtidos do
MetricKit .
Mantenha-se atualizado!