Simplifying Segues routing code with awesome switch-case in Swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
/** COMMON STUFF*/
/** ROUTE SPECIFIC */
if let destin = segue.destination as? LoginOTPVC, segue.identifier == "RequestOTP"{
//do some stuff
}else if let destin = segue.destination as? LoginPhoneVC, segue.identifier == "AskForPhoneNumber"{
//do some stuff
}else if let destin = segue.destination as? SignUpVC, segue.identifier == "TakeMeToSignUp"{
//do some stuff
}else if let destin = segue.destination as? ExternalWalletVC, segue.identifier == "ExternalWalletConnect"{
//do some stuff
}
/// this list can go on...
}
You just got greeted with a lot of routing code in swift. Liked it?
read on...
I love storyboards and I love Segues and after the Storyboard References that were introduced in iOS 9, I love them even more.
The code above must look very familiar. That's pretty much the routing code that goes into most of your view controllers. It looks ugly!
Let's fix this
In order to beautify the code above I needed to accomplish two things
- Go strict with the identifiers. (If you have a lot of String literals littered over in your code, DO NOT create a merge request yet.)
- Harness the power of switch-case. (Every time I google something about switch-cases I discover something new)
Go strict with the identifiers
Keep your strings in one place. But don't let the context fade away.
- struct (I cannot deny that structs are being exploited to act as namespaces for constants in swift )
- enum (The young cousin is all grown up now)
- String extension (The boring uncle)
What you choose depends on your programming style.
struct
struct SegueIdentifiers{
static let RequestOTP = "RequestOTP"
static let TakeMeToSignUp = "TakeMeToSignUp"
static let AskForPhoneNumber = "AskForPhoneNumber"
static let ExternalWalletConnect = "ExternalWalletConnect"
}
enum
enum SegueIdentifiers: String{
case requestOTP = "RequestOTP"
case takeMeToSignUp = "TakeMeToSignUp"
case askForPhoneNumber = "AskForPhoneNumber"
case externalWalletConnect = "ExternalWalletConnect"
}
String Extension
public extension String{
static let RequestOTP = "RequestOTP"
static let TakeMeToSignUp = "TakeMeToSignUp"
static let AskForPhoneNumber = "AskForPhoneNumber"
static let ExternalWalletConnect = "ExternalWalletConnect"
}
Harness the power of switch-case
Well, it is very popular feature of switch-case that you can check multiple values and address them in cases. I recently learned that you can also do type testing in switch- case . And it does not looks like a work-around.
Re-writing the welcome code in a little better way
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
/** COMMON */
if let destin = segue.destination as? BaseLoginViewController{
destin.associationMode = self.associationMode
destin.keyIdentifier. = self.keyIdentifier
}
/** ROUTE SPECIFIC */
switch (segue.identifier, segue.destination) {
case (.RequestOTP, is LoginOTPVC):
/** do stuffs or break*/
case (.AskForPhoneNumber, is LoginPhoneVC):
/** do stuffs or break*/
case (.TakeMeToSignUp, is SignUpVC):
/** do stuffs or break*/
case (.ExternalWalletConnect, is ExternalWalletVC):
/** do stuffs or break*/
default:
/** We have chosen String Extension path,
hence, default: is mandatory */
break
}
}
Sample Code
I am posting a rather simple demonstration in a swift playground file.
You can find it on my Github
Conclusion
I am sure most of you were aware of this and many of you will have even better and cleaner solution. Please share them with me.
Happy coding...
Awesome switch syntax in swift. Thanks Gaurav Keshre, this is really good one , waiting to see more :)