Fresh apps are usually able to startup in the time it takes for backboardd to animate from the icon to your first controller. But over the lifetime of an app, you can build up technical debt and slow things down.
One of the biggest offenders to slow startup, and slowness in general, is disk I/O. Even worse, doing I/O on the main thread.
With apps that have been around for a while, it can be daunting to be given a task to "make it faster". Here's a neat debugging tip I found that logs app-wide disk I/O and can help get you started.
Start by adding a symbolic breakpoint in Xcode. Do this before running your app.
In the Symbol field add -[NSData initWithContentsOfFile:]. This method is used by a lot of the disk I/O APIs that iOS developers end up using, so it should catch most of what you need.
You will want to print the first parameter of the method -initWithContentsOfFile:, the string path. Since this method is part of Foundation and already compiled, you can't just drop a breakpoint in the implementation.
Instead, you just need to print the first argument. You can find the parameter in the registers. The first two are self and _cmd, so you just need to print $esp+12 for 32 bit architectures or $rdx for 64 bit.
Add a Debugger Command action with the following command:
There is a lot of system disk I/O happening, and unfortunately all on the main thread. That's pretty much out of my control.
However, I can see that I'm reading the file Documents/latest.feed from the main thread (that's thread #1)! That's enough to give me a clue to track down where that file is read and maybe toss it off to a background queue.
If you want more detail, you could replace the thread info action with bt to print out a backtrace at each disk I/O event. That will output a ton of logs that you can then sift through.
If you wanted to go deeper, you could use tools like Facebook's chisel and fishhook. And if you wanted to get even lower, you could setup a breakpoint on fopen.
Hopefully this post helps track down pesky I/O issues. Happy hunting!
Recently I discovered a neat way to use Xcode 6 Playgrounds as a kind of unit test for a framework and walks through the problem I solved with it. You can jump directly to the project here if you'd like.
I've been tinkering around with a tiny library to do some math regarding aviation and flight paths. I'm more interested in creating a basic Air Traffic Control simulator app.
As a pilot, it's fun to learn more about the mechanics of aviation traffic.
I ran into an interesting problem when writing code to maneuver a plane between points in a 2-dimensional space.
Say you're flying near San Francisco at 120kts (in aviation, speed is in knots) with a heading of 360° (due North). Air Traffic Control asks you to make a standard rate turn towards the Palo Alto airport.
Flying a plane is actually pretty easy. To do this maneuver: turn the yoke, push the pedals, and when you're lined up with your destination, level off.
But in an iPad app there is only data: speed, heading angle, turn rate, coordinates, time.
I had to dust off my trigonometry and dig into a little bit of aviationmath to build a tiny library that made vector, circle, and velocity calculations a bit simpler.
Since these equations are the foundation of my simulation, I wanted to add unit tests so that as I add more features or refactor, the base project is solid.
But doing traditional unit tests in this case meant writing math to prove math. I'd like to actually see this stuff in action before I try to build an app around it.
That's when I remembered you can use layers and views in Xcode 6 Playgrounds. Maybe I could visualize my equations?
I created a new playground in my library called VectorKit.playground to try it out.
For starters, I needed to import my library. Unlike with Swift files, a playground does not automatically import your stuff.
I created a simple scene with a blank UIView. I had to slim down my units to points instead of nautical miles because playgrounds don't scale to fit.