MetricKit. Analyse des performances des applications iOS

image

Nouveau jouet


Nous continuons à nous familiariser avec le nouveau matériel d'Apple présenté à la WWDC. Cette fois, considérons MetricKit , un tout nouveau framework qui sert d'outil pour surveiller les performances des applications.

Tout le monde sait que mesurer les performances des applications pendant le développement est facile. Xcode montre la quantité de RAM utilisée et la charge du processeur, vous pouvez vous connecter en utilisant des instruments à un simulateur ou à un appareil testé et même écrire vos propres outils (pour plus de détails, consultez nos articles sur les packages d'outils personnalisés: partie 1 / partie 2 ). Le simple fait de comprendre l'importance de l'optimisation des performances ne vous permet pas de mesurer presque tout ce que fait l'application. Mais les choses se compliquent lorsque nous parlons de l'AppStore, si l'application développée est destinée à de vrais utilisateurs. Peu importe la précision avec laquelle vous testez votre application, dans des conditions réelles, il y aura toujours un tas de surprises qui affecteront les performances et l'expérience utilisateur. Bien sûr, il existe de nombreux outils pour collecter divers paramètres, mais la plupart d'entre eux sont limités par le SDK iOS , ainsi que par l'impact de la surveillance réelle sur le comportement des applications.

Cette année, Apple a décidé de combler cette lacune et a fourni aux développeurs un outil qui les aide à collecter et à analyser les mesures de performances des applications dans un environnement réel. Ils ont annoncé MetricKit (un cadre qui donne accès aux options fournies par le système d'exploitation) d'un onglet distinct dans l'organiseur Xcode 11, où vous pouvez trouver les paramètres d'application. Nous allons faire une pause dans MetricKit, car l'affichage des paramètres dans Xcode ne fonctionnera qu'avec les applications déjà publiées dans l'AppStore.

image

MXMetricManager


L'architecture du cadre est assez simple et directe. La partie centrale est occupée par la classe MXMetricManager , qui est une structure à élément unique qui fournit au développeur un large ensemble d'API de framework.

En général, le workflow se compose de 3 étapes principales:

  1. Vous initialisez MXMetricMnager et lui affectez un observateur.
  2. Si vous le souhaitez, vous pouvez implémenter vos propres métriques dans votre application à l'aide de l'API Signpost
  3. Et enfin, nous traitons maintenant les données reçues dans la méthode didReceivePayloads, c'est-à-dire envoyez-les à votre backend pour une analyse plus approfondie.

Les paramètres se présentent sous la forme d'un tableau d'instances de MXMetricPayload . La charge utile encapsule les ensembles de métadonnées et les horodatages. La charge utile métrique est un simple wrapper pour sous- classer MXMetric . Pour chaque type de paramètre, il est distinct.

Les types de métriques sont assez bien documentés par Apple, alors ne nous attardons pas sur cela trop longtemps. Cependant, vous devriez vous arrêter pour remarquer une chose intéressante - MXMetric fournit une API ouverte pour la sérialiser en NSDictionary ou JSON, ce qui, à mon avis, est un peu inhabituel.

Composants internes de MetricKit.


Dehors, MetricKit semble assez simple. Mais c'est toujours intéressant de voir comment tout fonctionne de l'intérieur. L'immersion dans quelque chose de plus profond est toujours une intrigue, si vous êtes confronté à une tâche spécifique. J'ai donc décidé que je voulais passer des paramètres avec des balises MetricKit, puis les faire me fournir des métriques mises à jour à tout moment. Bien sûr, vous pouvez utiliser ` Debug -> Simulate MetricKit Payloads` dans Xcode, mais id ne vous permet pas d'afficher vos propres données. Certes, ce n'est pas une équipe très utile, mais cela vous donne une direction dans vos recherches, et ça a l'air très drôle;)

Pour démarrer la tâche, nous avons évidemment besoin de MetricKit lui-même. Vous pourriez penser qu'il est facile d'obtenir un fichier binaire pour le framework, car Xcode l'affiche dans la liste des frameworks dès que vous l'ajoutez via la boîte de dialogue «Lier le fichier binaire aux bibliothèques». C'est une pensée très optimiste. Parce que si vous ouvrez MetricKit.framework , vous verrez le fichier MetricKit.tbd . Sa taille n'est que de 4 Ko . Évidemment, ce n'est pas ce que nous recherchons.

Alors que se passe-t-il vraiment ici?

TBD signifie «text-based dylib stub» et est en fait un fichier YAML avec une description dylib exportant des caractères et un chemin vers le binaire dylib. La liaison aux fichiers tbd réduit la taille du binaire. Plus tard, au moment de l'exécution, le vrai binaire dylib sera téléchargé à partir du système d'exploitation au chemin spécifié dans le fichier tbd. Voici à quoi ressemble le fichier lorsque vous l'ouvrez dans Xcode:

image

En utilisant le chemin du fichier tbd, vous pouvez facilement obtenir le binaire MetricKit pour de plus amples recherches, mais il existe une méthode encore plus simple.

Notre binaire d'application contient le chemin d'accès à chaque bibliothèque liée dynamiquement dans la section d'en-tête Mach-O. Ces informations sont facilement récupérées à l'aide de l'outil à l'aide de l'indicateur -l.

Voici la sortie du projet de test que j'ai créé:

→ otool -l ./Metrics | grep -i metrickit name /System/Library/Frameworks/MetricKit.framework/MetricKit (offset 24) 

Vous pouvez voir le même chemin que nous avons vu précédemment dans le fichier tbd. Ayant un fichier de framework binaire, vous pouvez jeter un œil aux éléments internes. Pour cela, j'utilise généralement le Hopper Disassemble . C'est un outil facile à utiliser mais très puissant pour une étude attentive des fichiers binaires.

Dès que le fichier binaire MetricKit s'ouvre, accédez à l'onglet 'Proc.' et développez la liste "Tags". Ici, vous pouvez voir tous les caractères exportés. En sélectionnant l'une d'entre elles (par exemple, MXMetricManager), nous verrons toutes ses méthodes et, après avoir sélectionné une méthode, nous verrons son contenu sur le côté droit:

image

Lorsque vous affichez la liste des méthodes MXMetricManager [ https://gist.github.com/deszip/88a258ae21d33dc75d7cbac9569c6ec1 ], il est très facile de remarquer la méthode _checkAndDeliverMetricReports. Cela semble être ce qu'il faut appeler pour que MetricKit fournisse des mises à jour aux abonnés.

Malheureusement, une tentative de l'appeler n'a pas conduit à un appel vers l'abonné, ce qui signifie probablement que ces paramètres ne seront pas fournis. Compte tenu de l'implémentation de la méthode, nous notons quelques choses intéressantes: elle énumère le contenu du répertoire / Library / Caches / MetricKit / Reports.

Il essaie ensuite de décompresser l'instance MXMetricPayload pour chaque élément sur le disque. Et enfin, il itère sur les abonnés enregistrés et appelle la méthode didReceive avec une liste de données.

Le problème est probablement qu'il n'y a pas de données dans / Library / Caches / MetricKit / Reports , mais nous savons que nous avons besoin de quelques instances archivées de MXMetricPayload. Donc, créons-les et mettons-les sur le disque avant d'appeler ' _checkAndDeliverMetricReports '. Encore une fois, le plan consiste à créer une instance de MXMetricPayload, puis à créer et à y ajouter tout type de MXMetric, puis à archiver l'instance de données sur le disque. Après tout, appelez la méthode ' _checkAndDeliverMetricReports ', cela devrait conduire à appeler notre abonné avec stub comme argument.

En parcourant les documents Apple sur la charge utile et les métriques, vous remarquerez peut-être qu'ils n'ont pas d'initialiseurs publics et que la plupart des propriétés sont en lecture seule. Alors, comment est-il possible d'instancier une classe?

Revenez à Hopper pour voir une liste des méthodes MXMetricPayload :

image

Vous pouvez voir ici ses initialiseurs et ses méthodes d'attribution des paramètres. L'appel de méthodes privées est facile en utilisant la classe NSInvocation et la méthode 'performSelector' en raison de la nature dynamique d'Objective-C.

Par exemple, nous allons créer des métriques pour le CPU et les ajouter à la charge utile. En utilisant ce lien, vous pouvez trouver le fragment de code complet: [ https://gist.github.com/deszip/a0cf877b07cc2877129e0aaef2fed1e4 ].

Et enfin, nous archivons tout ce que nous avons créé et écrivons les données dans le répertoire / Library / Caches / MetricKit / Reports .

Il est maintenant temps d'appeler la méthode ' _checkAndDeliverMetricReports ', qui devrait finalement conduire à un appel à l'abonné. Cette fois, nous passons les données avec la charge utile tronquée comme argument comme argument.

D'oĂą viennent les mesures


L'obtention de rapports est assez facile à implémenter via MetricKit , mais vous êtes probablement intéressé à savoir comment les rapports apparaissent dans le répertoire app / Library . Voici comment.

En creusant à l'intérieur du binaire MetricKit, j'ai remarqué cette méthode: '_createXPCConnection'. La vérification de son implémentation clarifie la situation - il construit une connexion NSXPCConnection pour le service avec le nom com.apple.metrickit.xpc et deux interfaces MXXPCServer et MXXPCClient pour les côtés client et serveur. Si vous regardez la description du protocole:

image

Conclusion


MetricKit est un outil unique et indispensable pour prendre en charge les performances de votre application en conditions réelles de production.

Malheureusement, il n'est actuellement pas possible de jeter un œil à l'interface utilisateur 'Metric' dans Xcode, à l'exception de ce qui a été montré lors d'une démonstration lors d'une session WWDC.

image

Il peut être un outil précieux pour faire passer l'expérience utilisateur au niveau supérieur en éliminant les problèmes de performances dans votre code.

Un inconvénient que je vois maintenant dans cet outil est le manque de détails pour chaque type: seule la séparation est la version de l'application, et vous ne pouvez pas voir de métriques pour un groupe spécifique de périphériques / versions de système d'exploitation / régions, etc.

Mais, bien sûr, il y a toujours la possibilité de vous envoyer des données pour un traitement ultérieur avec les informations importantes dont vous avez besoin. Vous pouvez l'attacher à des tâches dans votre traqueur de bogues et plus encore. Chez AppSpector, notre équipe travaille à étendre la fonctionnalité des outils de surveillance des performances à l'aide des données obtenues à partir de MetricKit .

Restez Ă  jour!

Source: https://habr.com/ru/post/fr468347/


All Articles