How to combine multiple guard statements in Swift
Ever since Swift introduced the guard statement, it has done wonders for the readability of my own code. Instead of using three or four nested conditionals just to unwrap a few optionals and check some state, I can replace all of that with a single guard statement.
Guard statements aren’t so new. They were introduced in Swift 2. But as I learn more and more about this language, I keep discovering new things. One of them is the ability to unwrap an optional and check its state, all in a single self-contained block of code.
Validating text entry with a single guard statement
Here’s a common scenario. You’re building an app that requires a username and a password. On the client side, you want to do some simple text validation before creating an account with the username and password that was entered.
Let’s say you just want to make sure each is at least 8 characters (definitely not enough validation but still a pretty common situation).
Let’s also assume that you are going to directly grab the username and password from the UITextfield where they are entered, and you plan to validate the text when the “create a user” button is pressed.
UITextfield has a “text” property that is an optional string. That means both the username and the password will have to be unwrapped before they can be used and checked for a character count. Guard statements are perfect for this.
Here’s how you would unwrap both the username and the password in a single guard statement.
Pretty cool, eh? I really like how you can show the same alert when either of these two values fail to unwrap. I know that’s not the ideal user experience, but sometimes you’re pressed for time and need a quick solution.
Of course there’s still a problem. You haven’t validated your input yet. Sure, you have managed to unwrap the username and passwords. You have a username and a password you can send off to your server logic, but you dont’ know if either is above your character count.
Until about two weeks ago, I would have done the character count validation in a separate guard statement. Boy would that have been silly. I would have needed to invoke the same “showAlert” method twice.
Nobody likes duplication when it can be easily avoided.
Now I know that you can do the unwrapping and the validation in a single guard statement, removing the duplication. Here’s what that looks like.
The trick is to format the guard statement to give each part of the validation process its own line. This makes it way more readable for anyone working on your team.
I like to put a tab between the guard keyword and the first unwrapped thing. Then I tab everything over to it on each line. The result is a nice and readable piece of validation code that removes the duplication.
Now you don’t need to have two separate statements calling the same “showAlert” method when they fail. You can do it all in one place.
What’s going on here?
The Swift compiler considers everything between a comma to be its own line of code. If you unwrap the username variable before the first comma, you can check it as an unwrapped value right after it.
It is important to note that there is an order of operations here. You have to unwrap an optional value before you can check it for some kind of state.
Are there limits to this?
I only do this sort of thing for quick validation that can be done in a few lines of code. I probably wouldn’t do it for a much more comprehensive validation method.
If you need a serious input validator, it is probably worth the effort to move your validation to a separate validator object. Otherwise your View Controller will have more validation logic than view management logic.
There is no hard and fast rule here. I’m not going to say “five lines is too much.” You just want to make sure your code is readable. Stuffing too much validation logic into a button action makes it less so.
Keep trying new things!
I must have read Apple’s Swift book some six times before I figured this one out. I don’t think I would have discovered it if I didn’t spend a little time just experimenting and seeing what I could do.
If you are new to Swift and haven’t figured everything out yet, you are in good company. Lots of us keep discovering new things, even after years of working with the language.
Support Practical iOS Development
Did you like what you see? Did I save you some time?
If so, please take a moment and support me on Patreon.
As a supporting member, you will get exclusive access to content, a vote on the topics covered, and at the higher levels, a “help me get unstuck” pass where I will personally help you fix a problem with your iOS app.