Chris Eidhof on Table View Controllers

Are you following Chris Eidhof? If you’re not, you should be. He first came across my radar a couple years ago when was part of the founding team behind objc.io. I loved the monthly issues of objc.io, and I definitely recommend going to check out their back catalog if you haven’t already (despite some of it being written in Objective-C). I also really like Deckset, an app Chris made for easily creating beautiful presentations. And finally, I also read his book Functional Swift which honestly might have been my first formal introduction to real world functional programming outside of some academic exercises during my education.

Recently, Chris gave a talk at try! Swift in Japan titled Table View Controllers in Swift. I wanted to bring the talk to your attention because I think it’s a good example of refactorings and improvements you can make while implementing a table view controller in Swift. Go take a look.

My Highlights

Custom Initializers For View Controllers

It’s so easy to get sucked into the world of Interface Builder. Don’t forget that there is life outside it. Chris provides some solid examples of how you can leverage custom initializers for UITableViewControllers to provide the initial set of data, and even closures for populating table view cells. Nothing revolutionary here, but again, something easy to forget if you are always living in a world of Interface Builder.

Fix All In Scope

Do you know about this magical Xcode tool? I didn’t until I watched this talk. In a lot of ways, this is why watching talks are worth their time in gold. Even if the talk itself isn’t on a topic you’re totally into, just watching someone else code can yield so many little tips and tricks that will help you improve your own development. During this presentation, I learned from Chris of the option in Xcode to “Fix All In Scope.” I’ve only tried this in a couple cases, and it is magical. As you are coding, you’ll forget to force unwrap an optional, or something that was originally declared a constant with let now needs to be a variable with var. Xcode can automatically fix a lot of these issues for you, and there’s actually a menu option with an accompanying keyboard shortcut- Command-Option-Control-F. Give it a try.

Screen Shot 2016-05-26 at 8.58.48 PM

Refactoring View Controllers Crosses a Line

Watching this video with a co-worker, he said something that I agreed with. A lot of videos you watch, and blog posts you read, about refactoring view controllers, eventually cross a line from being useful to academic. I feel like this happened in the later part of this talk. Eventually the generalizing and refactoring led to a point where no two screens in an app are going to be so similar that you can use a single view controller implementation and be able to entirely reuse it. Despite that, there are plenty of things to be learned from “academic” implementations.

Refactor Out State

One pattern I really love in Swift that comes from functional programming is being able to use computed properties to help define the “truth.” Here’s an example:

var history:[String]? = nil
var canUndo: Bool {
  get {
    return (history == nil)
  }
}

This is similar to what Chris shows in his presentation for managing a history of changes to an editable table view. What I like about this, is that pre-functional programming, and back in Objective-C, I would create a instance boolean variable canUndo that gets set to true or false throughout the flow of code based on changes to the table view’s contents. That code is super prone to bugs, particularly because ensuring that canUndo is the correct value in all cases. By using a computed property like this to consolidate the truth in one place helps remove that uncertainty and proneness to bugs.

Refactoring A Complicated Initializer

As Chris moves through his refactoring of a table view controller, at one point he arrives at a custom initializer for the table view controller that has many parameters. Besides being hard to read, it also doesn’t really lend itself to testing that well. Chris’s refactoring creates a struct that represents each parameter in the custom initializer. Now, just one thing to pass as a value to the initializer whether from calling code, or the tests. Easy, and concise.

Try It Yourself

I’d love to hear what you think after watching the video, what were your takeaways?

Happy cleaning.