MetricKitIOS开发

MetricKit框架详细解析(十) —— 基于MetricKi

2021-05-17  本文已影响0人  刀客传奇

版本记录

版本号 时间
V1.0 2021.05.17 星期一

前言

MetricKit由iOS13系统进引入,用来汇总和分析有关异常和崩溃诊断以及电源和性能指标的每个设备的报告。下面我们就一起来看下这个框架。感兴趣的可以看下面几篇文章。
1. MetricKit框架详细解析(一) —— 基本概览(一)
2. MetricKit框架详细解析(二) —— Improving Your App's Performance(一)
3. MetricKit框架详细解析(三) —— Reducing Your App's Memory Use(一)
4. MetricKit框架详细解析(四) —— Gathering Information About Memory Use(一)
5. MetricKit框架详细解析(五) —— Making Changes to Reduce Memory Use(一)
6. MetricKit框架详细解析(六) —— Preventing Memory-Use Regressions & Responding to Low-Memory Warnings(一)
7. MetricKit框架详细解析(七) —— Reducing Your App's Launch Time(一)
8. MetricKit框架详细解析(八) —— Reducing Disk Writes(一)
9. MetricKit框架详细解析(九) —— Improving App Responsiveness(一)

开始

首先看下主要内容:

了解如何使用MetricKit在iOS应用中监视电源,性能和诊断。内容来自翻译

接着看下写作环境:

Swift 5, iOS 14, Xcode 12

下面就是正文了。

长期以来,与Web应用程序不同,iOS应用程序被认为过于小巧轻便,不必担心监视其性能。但是,在现代,iOS应用程序变得越来越大,越来越复杂,并且在幕后的工作比以往任何时候都要多。现在,能够远程监视您的应用程序在许多不同设备上的运行方式至关重要。

某些iOS监视工具已经使用很长时间了。例如,您可以查询设备以查看正在运行的操作系统,或者是否正在使用Wi-Fi或蜂窝网络连接。另一种常见的做法是使用第三方分析工具(例如FirebaseNew Relic)来帮助捕获用户的真实感受。

但是,还有更多的诊断信息可以为iOS开发人员提供帮助!苹果公司听了,并在iOS 13中推出了MetricKit。使用此工具可以更轻松地从设备检索诊断数据,并将其用于iOS的远程监视。在本教程中,您将通过使用Xcode模拟接收诊断来探索MetricKit API

您可以通过以下方式做到这一点:


Looking Inside MetricKit

使用MetricKit,您可以从OS接收有关物理设备的诊断数据。它以JSON格式发送包含最近24小时数据的报告。例如,如果您要将这些数据中继到您自己的服务器上,这将很有帮助。然后,您可以可视化和分析该数据,并使用它们来提高应用程序的性能。

1. New APIs in iOS 14

MetricKitiOS 13起就存在,但在iOS 14中获得了一些重大改进。

首先,它引入了一个全新的有效负载(payload),称为MXDiagnosticPayload。以前,您仅收到MXMetricPayload。新的MXDiagnosticPayload提供了更多信息,例如崩溃和异常。这是苹果公司不断探索扩展框架方法的一个很好的例子。

此外,苹果推出了全新的性能指标MXAppExitMetric。该对象表示应用程序在前台和后台进行的退出的类型。此信息可以帮助您发现用户为何离开您的应用程序以及处于何种状态。


详细了解

在本教程中,您将使用Shopping Trolley,这是一个显示不同类型水果的简单购物清单的应用程序 —— 因为世界显然需要更多的水果清单应用程序。

注意:开始之前,您应该知道MetricKit仅可在真实的iOS设备上使用,并且与模拟器不兼容。因此,您需要插入真实的设备才能端到端运行此功能。

首先打开ShoppingListTableViewController.swift。 将此代码添加到文件顶部。

import MetricKit

现在,您可以访问MetricKit框架。

接下来,将此代码添加到viewDidLoad()中:

let metricManager = MXMetricManager.shared
metricManager.add(self)

这将访问框架提供的MetricManager。 然后将自身ShoppingShopTableTableViewController添加为metricManager的订阅者,这使它能够侦听来自OS的度量有效负载。

接下来,您只需要在ShoppingListTableViewController.swift的底部添加最后一段代码即可。

extension ShoppingListTableViewController: MXMetricManagerSubscriber {
  func didReceive(_ payloads: [MXMetricPayload]) {
    guard let firstPayload = payloads.first else { return }
    print(firstPayload.dictionaryRepresentation())
  }

  func didReceive(_ payloads: [MXDiagnosticPayload]) {
    guard let firstPayload = payloads.first else { return }
    print(firstPayload.dictionaryRepresentation())
  }
}

这是view controller上的扩展,符合MXMetricManagerSubscriber,其中包含两个可以从MetricKit接收有效负载(payloads)的方法。在这种情况下,接收有效负载时,只需将其打印到控制台即可。但是,在生产版本中,这是记录指标的好地方,例如对服务器进行API调用。

恭喜你!您已经集成了MetricKit

1. Understanding MetricKit APIs

该框架的接口非常简单明了,您可以看到Apple在开发过程中投入了多少想法。该框架包括:

2. Understanding MXMetricManager

MXMetricManagerMetricKit框架的心脏。这是共享对象,用于管理您的订阅以接收设备上的每日指标。

MetricKit在首次调用shared之后开始为您的应用程序累积报告。要开始接收度量标准报告,请首先使用符合MXMetricManagerSubscriber协议的类调用add(_ :)

然后,系统最多每天发送一次这些报告。每个报告均包含过去24小时内的指标以及以前未提交的报告。

Manager还具有remove(_ :),可让您随时删除订阅者。

3. Implementing MXSignpostMetric

使用MetricKit框架的一个巨大好处是,您现在可以将自己的指标合并到Apple提供的“out of the box”的指标中。 这非常强大,因为它意味着您可以向发送到服务器的报告中添加自定义指标,从而使您可以进一步挖掘。

首先添加一个自定义指标以在用户加载ShoppingListTableViewController时进行记录。 在现有fruit的正下方直接添加fruitsLogHandle

let fruitsLogHandle = MXMetricManager.makeLogHandle(category: "Fruits")

这将创建一个类似于bucket的句柄,用于保存您的自定义指标。

将此代码添加到viewDidLoad()的末尾。

mxSignpost(
  .event,
  log: fruitsLogHandle,
  name: "Loading Fruits TableViewController")

当视图控制器为用户完成加载后,mxSignpost将在fruits bucket中记录一个自定义指标。 这是一个简单的示例,您真的可以进一步扩展它。 例如,如果您的应用程序具有视频播放器,则记录流开始和结束的时间可能会很有用。

4. Implementing MXMetricPayload

您可以从MetricKit接收两个不同的有效负载(payloads)。 从MXMetricPayload开始 —— 这是一个封装每日指标报告的对象。 切记:要触发MetricKit每日报告,您必须插入真实设备! 如果您没有设备,则仍然可以通读本教程,因为提供了示例JSON有效负载。

在设备上构建并运行。

导航回Xcode,然后选择Debug ▸ Simulate MetricKit Payloads

这会触发一个示例每日报告,其形状与您将自然收到的报告的形状相同。 您应该在控制台上看到两个有效载荷。

 AnyHashable("cellularConditionMetrics"): {
    cellConditionTime =     {
        histogramNumBuckets = 3;
        histogramValue =         {
            0 =             {
                bucketCount = 20;
                bucketEnd = "1 bars";
                bucketStart = "1 bars";
            };
            1 =             {
                bucketCount = 30;
                bucketEnd = "2 bars";
                bucketStart = "2 bars";
            };
            2 =             {
                bucketCount = 50;
                bucketEnd = "3 bars";
                bucketStart = "3 bars";
            };
        };
    };

上面的代码示例复制了完整的有效载荷的一小段代码,显示了cellConditionMetrics。 有效负载的这一方面提供了有关您的用户在使用您的应用程序的最后24小时内经历的蜂窝状态的丰富数据。 通过告诉您它们在一栏,两栏或三栏上的服务次数,还可以进一步深入研究。 您可以使用bucketCount创建直方图。 想象一下,了解用户在某些信号条上花费的平均时间有多么大的帮助!

5. Understanding MXDiagnosticPayload

MXDiagnosticPayload封装设备提供的诊断数据,例如:

检查此有效负载的样本。

[AnyHashable("crashDiagnostics"): <__NSArrayM 0x283764390>(
{
    callStackTree =     {
        callStackPerThread = 1;
        callStacks =         (
                        {
                callStackRootFrames =                 (
                                        {
                        address = 74565;
                        binaryName = testBinaryName;
                        binaryUUID = "BE6FD323-B011-4E67-925B-A60362A1ADFA";
                        offsetIntoBinaryTextSegment = 123;
                        sampleCount = 20;
                    }
                );
                threadAttributed = 1;
            }
        );
    };
    diagnosticMetaData =     {
        appBuildVersion = 1;
        appVersion = "1.0";
        deviceType = "iPhone13,3";
        exceptionCode = 0;
        exceptionType = 1;
        osVersion = "iPhone OS 14.4 (18D52)";
        platformArchitecture = arm64e;
        regionFormat = GB;
        signal = 11;
        terminationReason = "Namespace SIGNAL, Code 0xb";
        virtualMemoryRegionInfo = "0 is not in any region.  Bytes before following region: 4000000000 REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL UNUSED SPACE AT START ---> __TEXT                 0000000000000000-0000000000000000 [   32K] r-x/r-x SM=COW  ...pp/Test";
    };
    version = "1.0.0";
}

上面的代码示例复制了完整负载的一小段,显示了crashDiagnostics。 这捕获了用户经历的崩溃。 它包括diagnosticMetaData以及有用的详细信息,例如操作系统和应用程序版本。

由于这是崩溃,因此有效负载还具有callStackTree,接下来将对其进行探讨。

6. Understanding MXCallStackTree

您对MetricKit的探索越多,就越能了解它如何为Apple自己的工具(例如Xcode Organizer)提供动力。 将应用发布给用户后,即使您不导入框架,您仍然可以在Organizer中查看由MetricKit生成的报告。

如您所见,此应用程序是实时运行的,具有可在Xcode中进行探索的真实数据。这是因为Apple免费提供大多数指标数据。但是,导入MetricKit框架意味着您可以进一步利用此数据并将其与您自己的指标链接。如果您的服务器支持自定义可视化效果,那么这也意味着您具有更大的显示灵活性。

MXCallStackTree是一个很好的数据示例,可以通过MetricKit更好地利用数据。您不仅可以获得有关崩溃和异常之类的报告,而且还可以获得JSON中提供的StackTrace。通过将崩溃链接到实际的堆栈跟踪信息,这对于进一步操作非常有用,因此您可以修复那些讨厌的错误。

7. Understanding MXAppExitMetric

MXAppExitMetriciOS 14中提供的全新对象,代表用户如何离开您的应用程序。退出类型包括:

用户可以出于多种原因退出应用程序。关闭应用程序可能是一个故意的决定,但有时操作系统会终止应用程序 —— 最糟糕的是,由于内存不足或发生异常。

在每个类别中,您可以得到以下数目的诊断信息:

请记住:每个类别通常是一个属性,然后具有与直方图结构化数据的关系。此外,它还链接到其他类,例如MXStackTree,这意味着您可以将某些应用程序退出链接回实际的崩溃。

那有多强大?功能强大!


Viewing in Organizer

Apple免费提供一定级别的数据,以在Organizer中可视化。这是将来自App Store Connect的数据直接集成到Xcode中的项目的一部分。

您无法访问OrganizerMetricKit提供的所有内容,但可以期望找到:

Apple已在此处汇总了最常用的数据,希望它们会继续添加到此列表中。

1. Generating Graphs & Reports

上面描述的每个部分已经呈现为各种图表。 通常,数据可视化为直方图以及JSON负载。 您将看到如何使用和显示MetricKit数据,从而产生巨大的效果。

上方显示了Scrolling指标的直方图。 它代表用户的滚动连接时间,从本质上讲,这是用户滚动视图所需的时间。 在此应用程序中,您可以看到滚动拖曳的大量减少,但随后突然增加。 当然,这是您要探索的东西,并弄清楚这些版本之间的变化。

这是来自App Store中实时应用的另一个示例。 此特定图显示Battery Usage情况,特别是用户在应用程序中处于活动状态时的电池使用情况。

细节水平真是太神奇了! 您可以在应用程序的每个部分(网络,显示等)查看受影响最大的电池使用情况。 在此示例中,该应用平均每天消耗用户电池的8.29%。 目前尚不清楚基准会是什么,但这使您能够探索并确定在何处进行改进。

MetricKit是监视iOS实时应用程序的重要一步。 为了有效使用,它确实需要考虑一些对您的用户重要的事情。 例如,如果您的应用程序包含大量执行滚动的内容(例如新闻阅读应用程序),则您可能需要关注滚动指标。

确定了重要内容后,就可以决定如何使用该数据以及如何显示它们。 例如,您可能有一个小的Vapor Swift API,它可以使用数据并将其存储在数据库中,而前端的小dashboard会将其转换为直方图。 集成MetricKit本身是最简单的部分!

有关将VaporMetricKit结合使用的深入视频课程,请查看Swift Vapor API for monitoring for iOS

想了解更多? WWDC上有一个精彩视频 —— What’s New in MetricKit

后记

本篇主要讲述了基于MetricKit的App中的电源监控,性能和诊断,感兴趣的给个赞或者关注~~~

上一篇下一篇

猜你喜欢

热点阅读