
Nuevo juguete
Continuamos familiarizándonos con el nuevo material de Apple presentado en WWDC. Esta vez, considere
MetricKit , un marco completamente nuevo que sirve como herramienta para monitorear el rendimiento de la aplicación.
Todos saben que medir el rendimiento de la aplicación durante el desarrollo es fácil. Xcode muestra la cantidad de RAM utilizada y la carga del procesador, puede conectarse utilizando instrumentos a un simulador o dispositivo bajo prueba e incluso escribir sus propias herramientas (para más detalles, consulte nuestros artículos sobre paquetes de herramientas personalizadas:
parte 1 /
parte 2 ). El solo hecho de comprender la importancia del ajuste del rendimiento no le permite medir casi todo lo que hace la aplicación. Pero las cosas se vuelven más complicadas cuando hablamos de AppStore, si la aplicación desarrollada está destinada a usuarios reales. No importa cuán cuidadosamente pruebe su aplicación, en condiciones reales siempre habrá un montón de sorpresas que afectarán el rendimiento y la experiencia del usuario. Por supuesto, hay muchas herramientas para recopilar varios parámetros, pero la mayoría de ellos están limitados por el
SDK de iOS , así como por el impacto de la supervisión real en el comportamiento de la aplicación.
Este año, Apple decidió llenar este vacío y proporcionó a los desarrolladores una herramienta que les ayuda a recopilar y analizar las métricas de rendimiento de las aplicaciones en un entorno del mundo real. Anunciaron
MetricKit (un marco que proporciona acceso a las opciones que ofrece el sistema operativo) de una pestaña separada en el organizador Xcode 11, donde puede encontrar la configuración de la aplicación. Haremos una pausa en MetricKit, porque la visualización de parámetros en Xcode solo funcionará con aplicaciones que ya están publicadas en la AppStore.

MXMetricManager
La arquitectura del marco es bastante simple y directa. La parte central está ocupada por la clase
MXMetricManager , que es una estructura de un solo elemento que proporciona al desarrollador un gran conjunto de API de marco.
En general, el flujo de trabajo consta de 3 pasos principales:
- Inicializa MXMetricMnager y le asigna un observador.
- Si lo desea, puede implementar sus propias métricas en su aplicación utilizando la API Signpost
- Y finalmente, ahora estamos tratando con los datos recibidos en el método didReceivePayloads, es decir envíelos a su backend para su posterior análisis.
Los parámetros vienen como una matriz de instancias de
MXMetricPayload . La carga útil encapsula conjuntos de metadatos y marcas de tiempo. La carga útil métrica es un contenedor simple para subclasificar
MXMetric . Para cada tipo de parámetro, es independiente.
Los tipos de métricas están bastante bien documentados por Apple, así que no nos detenemos en esto por mucho tiempo. Sin embargo, debe detenerse para notar una cosa interesante: MXMetric proporciona una API abierta para serializarlo en NSDictionary o JSON, que, en mi opinión, es un poco inusual.
Componentes internos de MetricKit.
Afuera, MetricKit parece bastante simple. Pero siempre es interesante ver cómo funciona todo de adentro hacia afuera. La inmersión en algo más profundo siempre es una intriga, si se enfrenta a una tarea específica. Así que decidí que quería pasar parámetros con las etiquetas MetricKit y luego hacer que me proporcionen métricas actualizadas en cualquier momento. Por supuesto, puede usar `
Debug -> Simulate MetricKit Payloads` en Xcode, pero id no le permite mostrar sus propios datos. Es cierto que este no es un equipo muy útil, pero le da dirección en su investigación y se ve muy divertido;)
Para comenzar la tarea, obviamente necesitamos MetricKit. Puede pensar que obtener un archivo binario para el marco es fácil, porque Xcode lo muestra en la lista de marcos tan pronto como lo agrega a través del cuadro de diálogo "vincular archivo binario a bibliotecas". Este es un pensamiento muy optimista. Porque si abre
MetricKit.framework , verá el archivo
MetricKit.tbd . Su tamaño es de solo
4kb . Obviamente, esto no es lo que estamos buscando.
Entonces, ¿qué está pasando realmente aquí?
TBD significa "trozo de dylib basado en texto" y en realidad es un archivo YAML con una descripción de dylib que exporta caracteres y una ruta al binario dylib. La vinculación a archivos tbd reduce el tamaño del binario. Más tarde, en tiempo de ejecución, el binario dylib real se descargará del sistema operativo en la ruta especificada en el archivo tbd. Así es como se ve el archivo cuando lo abre en Xcode:

Usando la ruta del archivo tbd, puede obtener fácilmente el binario MetricKit para futuras investigaciones, pero hay un método aún más simple.
Nuestro binario de aplicación contiene la ruta a cada biblioteca vinculada dinámicamente en la sección de encabezado Mach-O. Esta información se recupera fácilmente usando la herramienta usando la bandera -l.
Aquí está la salida para el proyecto de prueba que creé:
→ otool -l ./Metrics | grep -i metrickit name /System/Library/Frameworks/MetricKit.framework/MetricKit (offset 24)
Puede ver la misma ruta que vimos anteriormente en el archivo tbd. Tener un archivo de marco binario, puede echar un vistazo a los elementos internos. Para esto, generalmente uso el
Desmontaje de la
tolva . Es una herramienta fácil de usar, pero muy poderosa para un estudio cuidadoso de los archivos binarios.
Tan pronto como se abra el archivo binario MetricKit, vaya a la pestaña 'Proceso'. y expanda la lista 'Etiquetas'. Aquí puede ver todos los caracteres exportados. Al seleccionar uno de ellos (por ejemplo, MXMetricManager), veremos todos sus métodos y, después de haber seleccionado un método, veremos su contenido en el lado derecho:

Al ver la lista de métodos MXMetricManager [
https://gist.github.com/deszip/88a258ae21d33dc75d7cbac9569c6ec1 ] es muy fácil notar el método _checkAndDeliverMetricReports. Esto parece ser lo que hay que llamar para que MetricKit entregue actualizaciones a los suscriptores.
Desafortunadamente, un intento de llamarlo no condujo a una llamada al suscriptor, lo que probablemente significa que estos parámetros no se entregarán. Considerando la implementación del método, observamos algunas cosas interesantes: enumera el contenido del directorio / Library / Caches / MetricKit / Reports.
Luego intenta descomprimir la instancia de MXMetricPayload para cada elemento en el disco. Y finalmente, itera sobre los suscriptores registrados y llama al método didReceive con una lista de datos.
El problema es probablemente que no hay datos en
/ Library / Caches / MetricKit / Reports , pero sabemos que necesitamos algunas instancias archivadas de MXMetricPayload. Entonces,
creémoslos y colóquelos en el disco antes de llamar a '
_checkAndDeliverMetricReports '. Nuevamente, el plan es crear una instancia de MXMetricPayload, luego crear y agregar cualquier tipo de MXMetric y luego archivar la instancia de datos en el disco. Después de todo, llame al método '
_checkAndDeliverMetricReports ', esto debería conducir a llamar a nuestro suscriptor con stub como argumento.
Al revisar los documentos de Apple sobre la carga útil y las métricas, puede observar que no tienen inicializadores públicos y que la mayoría de las propiedades son de solo lectura. Entonces, ¿cómo es posible instanciar una clase?
Vuelva a Hopper nuevamente para ver una lista de los métodos de
MXMetricPayload :

Aquí puede ver sus inicializadores y métodos para asignar parámetros. Llamar a métodos privados es fácil usando la clase
NSInvocation y el método 'performSelector' debido a la naturaleza dinámica de Objective-C.
Como ejemplo, crearemos métricas para la CPU y las agregaremos a la carga útil. Usando este enlace, puede encontrar el fragmento de código completo: [
https://gist.github.com/deszip/a0cf877b07cc2877129e0aaef2fed1e4 ].
Y finalmente, archivamos todo lo que creamos y escribimos los datos en el
directorio / Library / Caches / MetricKit / Reports .
Ahora es el momento de llamar al método '
_checkAndDeliverMetricReports ', que eventualmente debería conducir a una llamada al suscriptor. Esta vez pasamos los datos con carga útil stubbed como argumento como argumento.
¿De dónde vienen las métricas?
Obtener informes es bastante fácil de implementar a través de
MetricKit , pero probablemente esté interesado en aprender cómo aparecen los informes en el directorio de la
aplicación / Biblioteca . Aquí es cómo.
Al excavar dentro del binario MetricKit, noté este método: '_createXPCConnection'. La comprobación de su implementación aclara la situación: crea una NSXPCConnection para servicio con el nombre
com.apple.metrickit.xpc y dos interfaces
MXXPCServer y
MXXPCClient para el cliente y el servidor. Si nos fijamos en la descripción del protocolo:

Conclusión
MetricKit es una herramienta única e indispensable para cuidar el rendimiento de su aplicación en condiciones reales de producción.
Desafortunadamente, actualmente no es posible echar un vistazo a la interfaz de usuario 'Métrica' en Xcode, excepto lo que se mostró durante una demostración en una sesión de WWDC.

Puede ser una herramienta invaluable para llevar la experiencia del usuario al siguiente nivel al eliminar problemas de rendimiento en su código.
Un inconveniente que veo ahora en esta herramienta es la falta de detalles para cada tipo: solo la separación es la versión de la aplicación, y no puede ver ninguna métrica para un grupo específico de dispositivos / versiones de SO / regiones, etc.
Pero, por supuesto, siempre existe la oportunidad de enviarse datos a usted mismo para su posterior procesamiento junto con la información importante que necesita. Puede adjuntarlo a tareas en su rastreador de errores y más. En
AppSpector, nuestro equipo está trabajando para expandir la funcionalidad de las herramientas de monitoreo de rendimiento utilizando los datos obtenidos de
MetricKit .
Manténgase al día!