Managing Multiple Segues in Swift

July 12, 2019

I had a problem in my iOS app that required an interesting solution. My app has a variety of information on the home page and using segues to transition to other pages was cumbersome. The segue system in iOS is a little weird because it relies on a callback function to manage any data that is passed to the destination view controller. This is weird because the same function is called regardless of the segue being used. How was I supposed to pass data to the destination when there can be multiple different destinations?

The solution to the problem was to implement a simple segue manager.

The code above is for a singleton class in Swift that manages nearly all of the segue operation. The only thing I don’t show is a call from the prepare() function within the view controller to the prepare() function in this singleton. It would typically look like this:

The singleton operation of the class is enforced by the private init() function. No other class can ever instantiate a class of this type. The singleton object itself is created as a member variable called “shared” (some people use “instance” as a name for the variable).

The SegueHandler class works by storing a closure that is passed to the class when the performSegue() function is called and then later calling that closure when the prepare() function is called. Instead of adding lots of code to the view controller to manage a variety of possible destinations for the segue, the closure handles it. The only assumption I made is that for every call to the OS performSegue() function, there will be a single call back to the prepare() function without it being possible to overlap multiple segues.

Here is how I use the SegueHandler class in some example code:

As you can see above, the closure code manages passing data to the destination view controller. Later when the prepare() function is called by the OS to prepare the segue, that function needs no knowledge about the segue, the destination, or the data. The closure is a way to cache the data, along with the code to sets it, for later use.

In looking for other way to use this same mechanism, I came across timers in Swift. Interestingly, the Swift (or is it ObjectiveC) Timer class supports a mechanism like this itself; The scheduledTimer() function accepts a closure that its called when the timer interval has elapsed. It would be odd that they did not think to do the same thing with segues except that tasing data to the destination view controller, and even having more than one destination from any one source, is probably not common. For me, I would want consistency in my library. For Apple, the expense probably doesn’t warrant the effort.

This code above is free to use. If copied and pasted in, please keep the copyright intact. If you write your own from memory after reading this, it’s all yours.