版本记录
版本号 | 时间 |
---|---|
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或蜂窝网络连接。另一种常见的做法是使用第三方分析工具(例如Firebase
或New Relic
)来帮助捕获用户的真实感受。
但是,还有更多的诊断信息可以为iOS开发人员提供帮助!苹果公司听了,并在iOS 13
中推出了MetricKit
。使用此工具可以更轻松地从设备检索诊断数据,并将其用于iOS的远程监视。在本教程中,您将通过使用Xcode
模拟接收诊断来探索MetricKit API
。
您可以通过以下方式做到这一点:
- 将
MetricKit
添加到入门应用程序。 - 将示例数据加载到
Xcode
中。 - 使用
MetricKit
查看应用使用统计信息。
Looking Inside MetricKit
使用MetricKit
,您可以从OS
接收有关物理设备的诊断数据。它以JSON
格式发送包含最近24小时数据的报告。例如,如果您要将这些数据中继到您自己的服务器上,这将很有帮助。然后,您可以可视化和分析该数据,并使用它们来提高应用程序的性能。
1. New APIs in iOS 14
MetricKit
自iOS 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在开发过程中投入了多少想法。该框架包括:
- 具有订户协议的管理器类。
- 每种指标和诊断类别的类。
- 报告数据的有效载荷
(Payload)
类。 - 测量单位的类,例如蜂窝信号强度条。这真太了不起了!
- 用于表示直方图之类的累积数据的类。他们又做了艰苦的工作!
2. Understanding MXMetricManager
MXMetricManager
是MetricKit
框架的心脏。这是共享对象,用于管理您的订阅以接收设备上的每日指标。
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
封装设备提供的诊断数据,例如:
- Performance:崩溃报告和异常
- Responsiveness:应用程序挂起率
- Disk Access:磁盘读写
检查此有效负载的样本。
[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
MXAppExitMetric
是iOS 14
中提供的全新对象,代表用户如何离开您的应用程序。退出类型包括:
Foreground exit
Background exit
用户可以出于多种原因退出应用程序。关闭应用程序可能是一个故意的决定,但有时操作系统会终止应用程序 —— 最糟糕的是,由于内存不足或发生异常。
在每个类别中,您可以得到以下数目的诊断信息:
- Normal App Exits - 正常应用退出:该应用从前台或后台正常退出。
- Abnormal App Exits - 应用程序异常退出:应用程序从前台或后台异常退出。
- Memory Resource Limit - 内存资源限制:由于使用过多内存,系统从前台或后台终止了该应用程序。
- Bad Access / Exception - 错误的访问权限/异常:系统从前台或后台终止了该应用程序,以尝试进行无效的内存访问。
请记住:每个类别通常是一个属性,然后具有与直方图结构化数据的关系。此外,它还链接到其他类,例如MXStackTree
,这意味着您可以将某些应用程序退出链接回实际的崩溃。
那有多强大?功能强大!
Viewing in Organizer
Apple免费提供一定级别的数据,以在Organizer
中可视化。这是将来自App Store Connect
的数据直接集成到Xcode
中的项目的一部分。
您无法访问Organizer
中MetricKit
提供的所有内容,但可以期望找到:
Crashes
Disk Writes
Energy Usage
Battery Usage
Hang Rate
Launch Time
Memory
Scrolling
Apple已在此处汇总了最常用的数据,希望它们会继续添加到此列表中。
1. Generating Graphs & Reports
上面描述的每个部分已经呈现为各种图表。 通常,数据可视化为直方图以及JSON
负载。 您将看到如何使用和显示MetricKit
数据,从而产生巨大的效果。
上方显示了Scrolling
指标的直方图。 它代表用户的滚动连接时间,从本质上讲,这是用户滚动视图所需的时间。 在此应用程序中,您可以看到滚动拖曳的大量减少,但随后突然增加。 当然,这是您要探索的东西,并弄清楚这些版本之间的变化。
这是来自App Store
中实时应用的另一个示例。 此特定图显示Battery Usage
情况,特别是用户在应用程序中处于活动状态时的电池使用情况。
细节水平真是太神奇了! 您可以在应用程序的每个部分(网络,显示等)查看受影响最大的电池使用情况。 在此示例中,该应用平均每天消耗用户电池的8.29%
。 目前尚不清楚基准会是什么,但这使您能够探索并确定在何处进行改进。
MetricKit
是监视iOS实时应用程序的重要一步。 为了有效使用,它确实需要考虑一些对您的用户重要的事情。 例如,如果您的应用程序包含大量执行滚动的内容(例如新闻阅读应用程序),则您可能需要关注滚动指标。
确定了重要内容后,就可以决定如何使用该数据以及如何显示它们。 例如,您可能有一个小的Vapor Swift API
,它可以使用数据并将其存储在数据库中,而前端的小dashboard
会将其转换为直方图。 集成MetricKit
本身是最简单的部分!
有关将Vapor
与MetricKit
结合使用的深入视频课程,请查看Swift Vapor API for monitoring for iOS。
想了解更多? WWDC上有一个精彩视频 —— What’s New in MetricKit。
后记
本篇主要讲述了基于
MetricKit
的App中的电源监控,性能和诊断,感兴趣的给个赞或者关注~~~