This time, I’ll be writing about an elegant solution to handling multiple segue identifiers. You guessed it! There will be protocols.

So today, we’re going on a journey of your choice. You choose: the red pill or the blue pill…

The Problem

Unfortunately, Segue Identifiers are hard-coded String based. When you add them in your Storyboard, you have to copy the string everywhere in your code – accidental misspellings are just ready to happen.

Swift

1

2

3

4

5

6

7

8

9

10

11

// ViewController.swift

@IBAction funconRedPillButtonTap(sender:AnyObject){

// I'm hard-coding my Red Pill segue identifier here 😬

performSegueWithIdentifier("TheRedPillExperience",sender:self)

}

@IBAction funconBluePillButtonTap(sender:AnyObject){

// I'm hard-coding my Blue Pill segue identifier again here 😬

performSegueWithIdentifier("TheBluePillExperience",sender:self)

}

And of course, if you decide to change the name of the segue identifier in the future, you have to change it in every place it was hard-coded… more potential for accidental copy / paste accidents and misspellings.

To mitigate this, I use enums to deal with my segue identifiers whenever there is more than one segue identifier in my ViewController.

Swift

1

2

3

4

5

6

// ViewController.swift

enumSegueIdentifier: String{

caseTheRedPillExperience

caseTheBluePillExperience

}

But that presents another set of problems… Mainly, it’s bloated and ugly:

You might use same view controller for multiple segues. Segue identifier makes it unique, not a destinationViewController.

Maxim Pervushin

Yes, you can use segue identifier to configure two identical view controllers different ways. But it is only 1% of all situations. I can hardly imagine when you may need to do such things.

Victor Ilyukevich

An example from top of my head. We use the same view controller to edit and to add a new object. From the list screen user can go to add a new object or to edit an existent one. In both cases there would be the same destinationViewController class, but different segue identifiers.

and afterwards it can be used like:
let destinationVc = destination(forSegue: segue) as CustomViewController

sure, it still works on run-time, but at least we’ll have a clean code and don’t have to downcast in our code, all the time.

Vik78

I’m sorry, I don’t think this is a better solution than hardcoding the values of the segue identifier. I really like getting the errors from the compiler, but you’re wrapping some functionality just so you get that. Now you have more code to be read and understood by the next programmer that comes by.

Your argument isn’t very strong. Natasha’s helper methods work just like any other means of removing duplication. Of course that code has to be understood at least once. Afterwards segue handling code is much more concise, though.

I like the result. I worry about local coupling of SegueHandlerType and SegueIdentifier, though. You cannot just invoke any segue possible anymore — it has to be included in the segue-handling view controller’s SegueIdentifier enum. That possibly entails duplication of identifiers. Any thoughts on that?

specialvict

Hi, Natasha, that is great pleasure to read your article, it’s really helpful.

I define segue naming constants in the view controllers (in the files, not classes) that will get presented by those segues. This way you have segue identifiers available in whole project, but they are not lumped up in single place and it also avoids identifier duplication. Performing segues stays the same too (just passing string constant as an argument).

alpha

it’s just a string, define a constant for each viewController (static let IDENTIFIER = “TheRedPillExperience” and refer to them in your function calls as RedViewController.IDENTIFIER, that’s what constants are for. Protocols enabled communication between two unrelated objects and not for storing seque identifiers

Farzad Sharbafian

Natasha’s answer is actually how Swift Developers in apple say we should use Swift.

Mark Patterson

This is neat. There seems to be a lot of tricks for extracting patterns once you master it.

Fred Adda

I love it! Adopted!

snit_ram

It would be great to also encapsulate the type of the destinationViewController to avoid downcasting all the time