Part 7 — Making a form with validation

Dhruvik Chevli
Hashtag by IECSE
Published in
8 min readMay 31, 2020

In this article, we are going to look at how we can make a form and validate it in Swift.

IECSE Crash Course: Development with Swift

This article is going to be the seventh article of the series IECSE Crash Course: Development with Swift. Through the course of 10 articles, we are going to make a small app which will display a set of users that we will fetch from the net. While making the app, we will cover some of the most important topics that every iOS developer must know.

If you haven’t been following the whole course, I’ll request you to go through and clone this repository as we are going to start from here.

Up till now, we have already presented the viewController in a navigationController. We’ll make the form in this viewController. So now, let’s have a look at how we are going to make the form!

SampleScreen.swift
struct User, we will be making an object of this.

In our form, we are going to have 6 textfields and are going to make a User object when submit button is pressed.

First, let’s make all the elements that we are going to need.

  1. One label that tells the user what the form is about.
  2. Six TextFields, one for each field for our User.
  3. One submit button.

Now that we know what elements our ViewController is going to have embedded in it, let’s start making the ViewController. We’ll write this code in the SampleScreen class.

In the above lines, we make a label that will work as a title to our viewController.

Before we start making the textfields, let’s take a look at the class UITextField. All the textfields that we are going to make are going to be objects of this class. Also, iOS allows us to configure and make several changes to our textfields. For this article, we are going to make one global function that will be responsible for configuring the textField.

Let’s first look at the function and then try and understand the lines of code in the function. This function will go outside our SampleScreen class.

The function setUpTextField requires 2 parameters, one is the textField that we want to configure and the other is the placeholder that we want to represent in our textField. Let's try and understand the code line by line. As we can see, most of the instance properties are self-explanatory, I’ll only be explaining certain properties that are important and a little difficult to understand.

  • textField.translatesAutoresizingMaskIntoConstraints = false , like we have also done previously, this is done so that we can manually set Anchor Constraints for our textField.
  • textField.placeholder = placeholder, this is the line where we configure what the placeholder should be for our textField. This placeHolder is one of the parameters that we received in the function.
  • Sometimes, when we tap on a textField, Phone Number, for example, you might want the keyboard that appears to be numeric. textField.keyboardType, is where we define the type of keys that you want to appear on the keyboard by default when the user clicks on a textField.
  • returnKeyType is the instance property that sets up the title of the return key on the keyboard.
  • If we want to change the colour of the textField, the syntax of attributedPlaceholder is how that is done.
  • If we want to change the colour of the border of the textField, it can only be done when you give your border some width.

Now that we have a function that configures our textField, let’s make 6 instances for the textFields that we are going to need in our ViewController.

Here, for every textfield that we instantiate, we call the setUpTextField function with the placeholder that we want the textfield to have.

Next, we add the submit button, which will be an object of UIButton.

Most of the code is responsible for configuring the appearance of the button. The line that interests us most is button.addTarget(..), which tells the button what function to call when it is pressed.

The syntax for this is,

button.addTarget(self, action: #selector(<functionToBeCalled>),for: .touchUpInside)

All the functions that you call from a button need to be exposed to Objective-C, that is what @objc does. For now, we are going to leave this function empty.

Once we are done with all this, we need to add these elements that we have instantiated into our SampleController. So as you might have guessed we do this in the function viewDidLoad(). We are going to set the elements up in our ViewController depending on how we want our view to look.

Once, we add all our elements to the SampleController, we call the function setUpView(). It’ll be in this function that we will set up constraints for all the elements.

Here, we have made an additional function setUpTF(_ tf:UITextField), so that we can avoid a little redundancy as many constraints for all the textFields are going to be same to maintain uniformity.

If you have doubts about the Auto Layout and constraints, I suggest that you go check out this article.

With this step our form is ready and all that is left is for us to write the function addUser, which we will do in the next section. If you have followed all the steps correctly until now, your SampleScreen looks like this.

Validation

When the submit button is pressed, we might want to make sure that all the fields are properly filled so that we have all the required fields to make our object. This is where validation comes in. Let’s have a look at how our addUser function looks.

First, we make a custom error, this is the error that we are going to throw when the user presses the button without all the fields.

Do-try-catch

In Swift, error handling is done with the do-try-catch block to respond to recoverable errors in our code. As per our need, what we want to do is make sure that all the fields are filled before we make a User object. The do-try-catch block can be thought of as an if-else conditional. When we put some statement in do, we try certain things that we know might give an error. When that happens we throw the appropriate error and we leave the do block and enter the catch block, this is where we handle the error appropriately.

The do-try-catch block is preferred because the other alternative would be to force-unwrap the object, but when you do that it means that your app will crash if the unwrapped value is null. Hence, that is only done when you are sure that the value you are unwrapping will not be nil. Avoid force-unwrapping as much as possible.

In our code, we also use the guard statement. This can also be imagined like an if-else block. What happens here, is that if the condition after the guard statement is evaluated to false, the else block is invoked. One thing to note when using guard, is that it can only be used to “transfer program control out of scope”. This is a fancy way of saying that the body of the guard block, i.e. what’s inside the squiggly brackets, needs to exit the function. Hence in the else block, you are only allowed to use the following :

  • return, to exit a function or closure
  • break, to exit a loop like for
  • continue, to continue to the next loop iteration
  • throw, to exit a function and throw an error.

In our code, what we do is try to unwrap the text in all the textFields one by one, there is a good chance that one of the textFields might be empty and give nil on being unwrapped, this is the case where our else block gets executed. It is this else block that we throw an error.

Once we have taken care of all the fields that we need, ie if we have not entered the else block of the guard statement, we will make our object. So before we can make the User object, we are going to make an object for the city and company of struct Address and Company. We will use these objects to make the object for our new user.

Next, we reset all the other fields so that new data can be entered.

It is in the catch block where we will take care of the case that an error was encountered while unwrapping the values, ie if one of the textFields was empty. Here, we are just going to print the error. But actually, we can also make a pop up that asks the user to fill in the fields properly.

Wrapping up

In this tutorial, we have seen how we can make forms and validate them. We created an object for user which in the next tutorial we are going to pass to our ViewController and we will add this user to our tableView using Delegates.

Congratulations🎉! You have completed the 7th tutorial!!

All of the above-written code is available on Github. Watch this space for more interesting challenges, up next in this series!

Confused about something? Let us know in the responses below. 😄

--

--