Better Programming

Advice for programmers.

Follow publication

Form Validation in iOS Apps Made Easy With RxSwift

Mohd Hafiz
Better Programming
Published in
6 min readApr 28, 2021

Male on a hammock in front of a waterfall
Photo by Jeremy Bishop on Unsplash

I know that “RxSwift” itself sounds like a big and difficult thing. I was feeling the same when I started working on it. We are all learners. One of the best ways to learn is by adopting the implementation into an existing project. In this article, we will focus on the implementation of form validation in RxSwift.

RxSwift is Reactive Extensions (Rx) for Swift language. It is a well-known library and widely used by iOS developers, especially in MVVM patterns. For more understanding on definition and overview, you may refer to good articles written in Hackernoon and Raywenderlich.

Observable, Subscriber and Subjects

First, you should know that RxSwift is basically about Observable and Subscriber. Both are important elements in RxSwift.

  1. Observable. As the word describes, it is any variable or object that can be observed and able to notify its observers. So, it will keep telling the observer about event changes.
  2. Subscriber aka observer. It subscribes to the Observable object to continuously receive notifications.
  3. Subjects. Simple, it has both capabilities: the Observable and Subscriber.

Data Binding

A process to bind a data to intended action or UI.

For example, in a “Reset Password” form, the user is required to enter a valid email so that the submit button will be enabled to click.

In this case, we need to have the following:

  1. A variable, let’s say, isValidEmail (a Bool), in which the value is determined based on the email entered in a TextField (isValidEmail subscribes to the TextField changes).
  2. Then, the value of that isValidEmail is bound to a submit button. So, whenever isValidEmail is true, the button will be enabled. This is its .normal state. As soon it becomes false, the button will change to its .disable state. Cool!

In short, a value can bind to a UI and vice versa.

Dispose Bag

In RxSwift, Subscription cannot be disposed of by itself. Thus, we need to create a bag, which is used to collect all disposable subscriptions in order to properly avoid memory leaks. You will see the usage in the code.

Photo by Kinga Kołodziejska on Unsplash

There are two scenarios that we will work on:

  1. Reset password form (single TextField validation)
  2. Sign up form (multiple TextFields validation)

Reset Password Form

Gif. Typing “hello@example.com” into the textfield

In this section, we are going to use the observer for the email TextField. Once the value becomes a valid email, the “Submit” button will automatically become enabled and vice versa. Wow! 🤩

First, create a new project and add a UITextField and UIButton outlets. Then, link the outlets to ViewController:

Link outlets to ViewController

Set the Submit button properties for disabled state with .gray text color to differentiate the button state during the rx emitting event (you may set the text color for .disabled programmatically).

Now, we need to update our ViewController. Here is the code, and the explanation is after it:

  1. Import the RxSwift and RxCocoa library at the top.
  2. Add new variable call emailSubject. You will notice that we are using BehaviorRelay for the email variable, and it is type String (optional). It is a Subjects type, and it can receive a value from the TextField and will also emit events to subscriber every time the value changes (including the initial value). The “value” at the end of the row is a parameter for the initial value required.
  3. Add disposeBag as explained before (to deallocate memory).
  4. Setup the UI Bindings. Add a new function setupBindings(), and add code to bind any changes in the TextField into emailSubject.
  5. emailSubject will emit event if these steps occur. Check the flow.
    a. In map(), once the event is received, we map (transform) the value into Bool to check if the email string is correct (using simple String extension validateEmail()— check the bottom of the code.
    b. Then, we bind the result into submitButton to change rx state of isEnabled
    c. Last, dispose of the subscription into that bag.
  6. A String extension with a function to validate email format using RegEx.
  7. A String extension with a function to validate email format using RegEx.

Yes, we’re done with our first validation form. The submit button is now secure and cannot be clicked, unless the email is valid.

Extra Tips 💡

Actually, number five can be simplified a bit by adding a new variable, isValidEmail as Observable<Bool>, to capture the emailSubject result. Here’s the code:

Sign Up Form

In this section, we are going to do the same validation but with multiple fields. The form has three fields: name, email, and password. The requirements are:

  1. Name cannot be empty or nil
  2. Check if the email is valid
  3. Make sure password format is correct with more than six characters (this is just an example, you may add your own rules using regex or other methods)

To make our code cleaner, we will break it into ViewController and ViewModel. ViewController will handle the UI setup and binding, while the ViewModel will handle the validation logic.

ViewModel

Before we start updating our Controller, let’s complete our ViewModel as the Controller dependency. Add a new file called “SignUpViewModel.swift” and add a new class SignUpViewModel as shown below:

The explanation of the previous code is below.

  1. Add necessary variables to listen to the event change on the TextField including name, email, and password.
  2. The unique part is isValidForm. Previously, we only checked on a single field. Now, we combine all observables values and return them as one result using combineLatest(). So, in ViewController, the subscriber will simply observe isValidForm to ensure the form is currently in a valid state.

ViewController

First, create a new UIViewController called SignUpViewController, and add a new scene to storyboards with TextField and Button outlets. Then, connect them with the SignUpViewController.

Let’s take a look at SignUpViewController. The code is simplified when we are using viewModel:

From this ViewController we understand the following:

  1. Add outlets for textfields and button (make sure to set .disable state of button title color to gray as we did before)
    submitButton.setTitleColor(.gray, for: .disabled)
  2. Create viewModel object from class SignUpViewModel to handle the validation
  3. Bind TextFields to viewModel
  4. Bind value of isValidForm to submit button to automatically change the button state.

Awesome. Now you have mastered form validation using RxSwift. Try to implement them in your existing projects gradually, perhaps with more rules and variation. You may also explore other methods of doing the form validation. Download my full source code here.

Hopefully this article will help you learn RxSwift. Thanks for reading. Don’t forget to clap 👏 and share with your friends. Feedback is most welcome.

References

https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/1-hello-rxswift

https://hackernoon.com/mvvm-rxswift-on-ios-part-1-69608b7ed5cd

https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/3-subjects#toc-chapter-007-anchor-001

https://github.com/ReactiveX/RxSwift

Mohd Hafiz
Mohd Hafiz

Written by Mohd Hafiz

iOS Developer focusing on Swift — “Read, learn & practice!”.

Responses (1)

Write a response

Great work Hafiz, I've lost your contact since I left RAS, would be nice to connect to you again - Andrew Cao