Swift Pills

Dosis rápidas de conocimiento sobre Swift y desarrollo en ecosistemas Apple

¿Tu app se cierra inesperadamente y Xcode Organizer no te da suficiente información? MetricKit es la solución

🔍 Xcode Organizer nos proporciona métricas esenciales como crashes, consumo de batería, tiempos de arranque y uso de memoria. Sin embargo, se queda corto cuando necesitamos diagnosticar la terminación abrupta de la app o profundizar en problemas complejos de rendimiento que afectan a usuarios reales.

MetricKit es el framework que Apple introdujo en iOS 13 para llenar este vacío. Nos permite recopilar diagnósticos detallados a nivel del sistema operativo sobre cómo se comporta nuestra app en dispositivos reales. Recibe informes agregados cada 24 horas con datos de rendimiento, batería y diagnósticos de la jornada anterior.

🎯 La integración es sorprendentemente sencilla. Primero, importas el framework y creas una clase que conforme al protocolo MXMetricManagerSubscriber:

import MetricKit

final class MetricReporter: NSObject, MXMetricManagerSubscriber {
    func didReceive(_ payloads: [MXMetricPayload]) {
        // Procesar métricas de rendimiento
    }
    
    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        // Procesar diagnósticos de crashes
    }
}

📊 Luego, registras el suscriptor en el AppDelegate para recibir los informes:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    private let metricReporter = MetricReporter()
    
    func application(_ application: UIApplication,
                    didFinishLaunchingWithOptions options: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        MXMetricManager.shared.add(metricReporter)
        return true
    }
}

💥 Con MXMetricPayload obtienes datos cruciales sobre terminaciones de tu app. Por ejemplo, puedes extraer las razones exactas por las que el sistema la cerró:

func didReceive(_ payloads: [MXMetricPayload]) {
    for payload in payloads {
        if let exitMetrics = payload.applicationExitMetrics?.backgroundExitData {
            // Salidas anormales
            let abnormalExits = exitMetrics.cumulativeAbnormalExitCount
            // Terminaciones por límite de CPU
            let cpuExits = exitMetrics.cumulativeCPUResourceLimitExitCount
            // Terminaciones por presión de memoria
            let memoryExits = exitMetrics.cumulativeMemoryPressureExitCount
            // Terminaciones OOM
            let oomExits = exitMetrics.cumulativeMemoryResourceLimitExitCount
        }
    }
}

🔧 Para métricas personalizadas, puedes usar Signposts y medir secciones críticas de tu código:

let handle = MXMetricManager.makeLogHandle(category: "ImageProcessing")

mxSignpost(.begin, log: handle, name: "HeavyOperation")
// Tu código pesado aquí
mxSignpost(.end, log: handle, name: "HeavyOperation")

📈 Un detalle importante: los informes incluyen propiedades timeStampBegin y timeStampEnd que delimitan el período cubierto. Esto es fundamental porque un payload puede contener datos de múltiples versiones de tu app si el usuario actualizó durante esas 24 horas.

🎨 Lo mejor es que ambos tipos de payload ofrecen representaciones en JSON y diccionarios, facilitando su envío a tu propia API:

let jsonData = payload.jsonRepresentation()
let dictionary = payload.dictionaryRepresentation()
// Enviar a tu servicio de analíticas

⚙️ Para probar en desarrollo, conecta un dispositivo físico y usa Debug > Simulate MetricKit Payloads en Xcode. El simulador no es compatible con MetricKit.

💪 La integración no afecta al rendimiento porque iOS recopila las muestras de forma nativa mientras la app está en uso. No añades overhead adicional como con algunas soluciones de terceros.

👨‍💻 MetricKit transforma la monitorización de apps en producción. Te da visibilidad real sobre arranques, terminaciones, crashes y uso de recursos que antes eran invisibles. ¿Ya lo estás usando en tus proyectos?

Posted in

Deja un comentario