Optimizing for responsiveness is a huge part of making great apps. Before we can optimize though, we'll need to measure. Xcode and Instruments offer some incredible tools to do "deep-dives" for answers (Bite #68, Bite #113), but often we just want to keep an eye on our app's performance and respond as needed.

Today we'll try out a library called GDPerformanceView by Gavrilov Daniil that lets us easily monitor our app's rendering speed and CPU usage in the device's status bar while we use the app. Let's begin.

We'll install GDPerformanceView and head over to our AppDelegate. We'll add a bit of code:

GDPerformanceMonitor.sharedInstance.startMonitoring { (textLabel) in
  textLabel?.backgroundColor = .black
  textLabel?.textColor = .white
}

Here we're telling GDPerofrmanceMonitor to start its engines, then customizing the look and feel of the label that appears in the status bar.

When we Build & Run, here's what we get:

Neat! By default GDPerformanceView will show the app and device version. This is great in some cases (QA testing, beta builds), but in our case we don't really need it. Let's them both off:

GDPerformanceMonitor.sharedInstance.appVersionHidden = true
GDPerformanceMonitor.sharedInstance.deviceVersionHidden = true

Beautiful. Now we'll always know exactly how well our app is behaving, and we'll be able to identify issues as they happen.

GDPerformanceView has one more trick up its sleeve. 🎩

We can actually subscribe to performance updates and do whatever we'd like with the data.

Let's try this out. First we'll subscribe to updates by making our AppDelegate conform to the provided GDPerformanceMonitorDelegate protocol:

extension AppDelegate : GDPerformanceMonitorDelegate {
  func performanceMonitorDidReport(fpsValue: Float, cpuValue: Float) {
    // TODO
  }
}

Then, we'll set it as the delegate for the shared GDPerformanceMonitor in our didFinishLaunching:

GDPerformanceMonitor.sharedInstance.delegate = self

Nice. Now we need to do something interesting with these updates. Let's use the Taptic Engine (Bite #269) to provide some force feedback if we hit the CPU too hard:

func performanceMonitorDidReport(fpsValue: Float, cpuValue: Float) {
  if cpuValue > 50 {
    UIImpactFeedbackGenerator(style: .heavy)
      .impactOccurred()
  }
}

Neat! We could also toss these values into an array somewhere and use it to build charts, etc.

Learn more about GDPerformanceView at git.io/gdperformance.