Blog

Swift Tip: Type-Safe Initialization using Storyboards (Part 1)

Love them or hate them, Storyboards are used in many iOS projects. In this week’s Swift Tip, we look at a simple way to make them more robust.

When you present a new view controller using Storyboards, it’s usually a multi-step process: first, the segue is triggered, and at a later step, you configure the segue. This makes it easy to miss configuration code.

For example, in the code below, we set the two properties that the PlayViewController needs:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail",
        let playVC = segue.destination as? PlayViewController {
        playVC.context = self.managedObjectContext
        playVC.recording = selectedRecording
    }
}

It’s easy to forget one of the above properties, because it’s often not clear which properties are required, and because view controllers typically have many stored properties. What’s more, when you’re in the RootViewController, you don’t always have all the details of PlayViewController to hand. Because of the multi-step initialization process, we can’t put this in the initializer either (the PlayViewController has already been constructed by the time we end up in prepare(for:sender:)).

As an improvement, we can adopt the convention that each view controller has a configure method which takes the necessary parameters:

func configure(context: NSManagedObjectContext, recording: Recording) {
    self.context = context
    self.recording = recording
}

Now, in prepare(for:sender:) you can rely on autocomplete and the compiler to make sure you provide all the necessary parameters:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetail",
        let playVC = segue.destination as? PlayViewController {
        playVC.configure(context: self.managedObjectContext, recording: selectedRecording)
    }
}

This approach is much more robust when refactoring; for example, we can add another required parameter to the configure method, and the compiler will indicate all the places we need to change. As long as we are disciplined about calling configure rather than setting the properties manually, we’re safe.

In Part 2, we show an alternative approach taken from our new book, App Architecture. In the MVVM-C implementation, we use Storyboards to lay out the view controllers, but provide static wrapper methods that construct the view controllers with the required parameters. Instead of segues, we move the logic into a coordinator class, and manually trigger presentation.

We demonstrate a similar refactoring in Swift Talk Episode 5.


  • Watch the Full Episode

    Architecture

    Connecting View Controllers

    We refactor our code by moving the app's flow from the storyboard into a separate coordinator class. This avoids view controllers having implicit knowledge of their context.

    Episode 5 Β· July 8, 1985

  • Related Episodes

Stay up-to-date with our newsletter or follow us on Twitter.

Back to the Blog

recent posts