Monitoring for iOS with MetricKit: Getting Started

Learn how to use MetricKit to monitor power, performance, and diagnostics in your iOS apps. By Adam Rush.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 2 of this article. Click here to view the first page.

Understanding MXDiagnosticPayload

MXDiagnosticPayload encapsulates diagnostics data given by the device, such as:

  • Performance: crash reporting & exceptions
  • Responsiveness: application hang rate
  • Disk Access: disk read & writes

Inspect a sample of this payload.

[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";
}

The code sample above reproduces a small snippet of the full payload, showing crashDiagnostics. This captures a crash the user experienced. It includes diagnosticMetaData with helpful details like OS and app version.

Because this is a crash, the payload also has callStackTree, which you’ll explore next.

Understanding MXCallStackTree

The more you explore MetricKit, the more you can see how it powers Apple’s own tools, such as Xcode Organizer. Once your app has gone live to users, you’re still able to see the reports generated by MetricKit in Organizer, even if you don’t import the framework.

MetricKit data for Launch Time displayed in Xcode Organizer

As you can see, this app is live and has real data to explore right in Xcode. This is because Apple presents most metrics data for free. However, importing the MetricKit framework means you can leverage this data further and link it with your own metrics. It also means you have greater flexibility on how it’s displayed if your server powers custom visualizations.

MXCallStackTree is a great example of data to leverage better via MetricKit. Not only do you get reports for things like crashes and exceptions, but you also get the StackTrace provided in JSON. This could be extremely useful in going further by linking crashes to actual stack traces, so you can fix those pesky bugs.

Understanding MXAppExitMetric

MXAppExitMetric is a brand-new object provided in iOS 14 that represents how users are leaving your app. Exit types include:

  • Foreground exit
  • Background exit

Users could exit an app for many reasons. It could be an intentional decision to close the app, but sometimes the OS terminates the app — at worst, because of low memory or an exception.

In each category, you can get diagnostics on the number of:

  • Normal App Exits: The app exited normally from the foreground or background.
  • Abnormal App Exits: The app exited abnormally from the foreground or background.
  • Memory Resource Limit: The system terminated the app from the foreground or background for using too much memory.
  • Bad Access / Exception: The system terminated the app from the foreground or background for attempting an invalid memory access.

Remember: Each category is usually a property that then has relationships back to the histogram-structured data. Plus, it also links to other classes, such as MXStackTree, which means you can link certain app exits back to actual crashes.

How powerful is that? Incredibly powerful!

Viewing in Organizer

Apple provides a certain level of data for free to visualize in Organizer. This is part of a project to incorporate data from App Store Connect right in Xcode.

Organizer selected in Xcode

You don’t get access to everything provided by MetricKit in Organizer, but you can expect to find:

  • Crashes
  • Disk Writes
  • Energy Usage
  • Battery Usage
  • Hang Rate
  • Launch Time
  • Memory
  • Scrolling

Disc Writes selected in Xcode Organizer

Apple has compiled the most commonly used pieces of data here, and hopefully, they’ll keep adding to this list.

Generating Graphs & Reports

Each section described above is already rendered into various charts. Usually, data is visualized as a histogram as well as a JSON payload. You can see how MetricKit data can be consumed and displayed to great effect.

MetricKit histogram of Scroll Hitch Rate in Xcode Organizer

A histogram for Scrolling metrics is shown above. It represents scrolling hitch time for your users, which is essentially how long it takes before they can scroll on your views. In this app, you can see a massive decrease in scroll hitching, but then a sudden increase. This is certainly something you’d want to explore and figure out what changed between those versions.

Metric histogram of On-Screen Battery Usage in Xcode Organizer

Here’s another example from a live app in the App Store. This particular graph displays Battery Usage, specifically battery usage for when users are active in the app.

The level of detail is quite amazing! You can see per section of your app — Networking, Display, etc. — what most affected battery usage. In this example, the app takes 8.29% of the user’s battery per day on average. It’s unclear what the benchmark would be here, but this gives you the power to explore and determine where to make improvements.

Where to Go From Here?

You can download the final project using the Download Materials button at the top or bottom of this tutorial.

MetricKit is a massive step forward in monitoring for iOS your live apps. To use effectively, it does require some thinking about what’s important for your users. For example, if your app has lots of content that performs scrolling — such as a news-reading app — then you might want to focus on scrolling metrics.

Once you’ve determined what’s important, you can decide how to consume that data and how to present it. For example, you could have a small Vapor Swift API that consumes the data and stores it in a database with a small front end dashboard that converts it into histograms. Integrating MetricKit itself is the easiest part! :]

For an in-depth video course on using Vapor with MetricKit, check out a fully working Swift Vapor API for monitoring for iOS.

Want to learn more? WWDC has a fantastic video on What’s New in MetricKit.

Now on to monitoring for iOS apps and improving your users’ experience! If you have questions or comments, please join the discussion below.