iOS developers, what is your code hiding from you?

I will usually keep the mailing list exercises separate than the blog, since the blog is more mentor-y in nature. Technical skills are easier to practice in your own time after reading an email than after you’re reading a blog post.

However, some readers have emailed me with their answers and I just have to talk about the exercise.

Your goal with this 15-minute action item is to decrease your resilience to unoptimized code. I want you to hate it. I want you to twitch when you see the first example above. Copy ViewController.swift‘s `viewDidLoad` function to a text file. Fix the pyramid of doom using guards and send me the answer. Don’t use Xcode; don’t use a compiler; do not pass go and collect $200.

I only mentioned the pyramid of doom, but I was hoping some of you wouldn’t stop there. I wanted you to twitch and hate the remaining code after you fixed the pyramid of doom. There’s much more hidden in that code.

The original code.

From the original code you can see that the pyramid of doom needs fixing. Its ever-increasing indentation and the chain of ifs reduce readability dramatically. Fixing it is actually straightforward, and a few of you got it right. There’s a few variations, but my first instinct would be to use filter and then a guard let ... = filtered.first.

An example answer. Don’t worry about syntax errors.

That completes the exercise and if you reached a point similar to this, kudos. You’re exactly at the level I’d expect. Proficient and understands code 💯

However, I was secretly hoping I’d get answers that addressed the code smells that appeared after the pyramid is fixed. For example, let’s step back a bit and see the related function beginSession.

beginSesion and var captureDevice are used inside viewDidLoad.

beginSession is a code smell. It’s a single-use function and it’s obfuscating the fact that var captureDevice is not needed as an instance variable. You also don’t need to use try if you’re only going to print the error.

My solution

As you can see from my solution, there’s several improvements and small fixes:

  • Constants and variable names are more explicit (videoCaptureDevices vs. devices).
  • Replaced the for with a filter.
  • Removal of optionals (captureDevice used to be an optional)
  • In-lined beginSession, to increase readability and reduce jumping around.
  • var captureDevice is an instance variable, but it’s only used in beginSession and so it’s no longer needed.

And my solution in turn discovers more code smells!

  • var session may only be needed in viewDidLoad.
  • We now clearly see a point of failure: captureDevice being nil or not being able to add it as an input to session. Do we want to notify the user? Stop execution altogether?

As you can see, the original code presented an obvious code smell (the pyramid of doom) but fixing it is not enough. You should always be striving to fix the tiny things around the code.

In my book, we’ll be dissecting code much like we did right now but with much more detail and with the exact rules that I use to code. You’ll be able to learn my style and spot all of these code smells by following me around as I deconstruct code and make it better.

If you liked this exercise, I send 1 weekly exercise every Friday via email. If you’re interested, sign up and I’ll see you soon!