Refactor validation logic from UIViewController to a factory of UITextFields
There is no doubt that filling in data into forms is one of the most typical features that we need to provide in our iOS apps. Each app is different and it has different types of data like names, ids, passwords, emails… Moreover, data must be validated before being sent to our servers.
Due to an inherit MVC architecture, it would be common to find many business logic inside our UIViewController class, this fact is also applied to form validations that are usually managed at UITextFieldDelegate methods ending up in many duplicated code for the same type of validation. To avoid this issue, I would like to show an approach that solves the problem of validating same kind of textField in many different scenes inside our app, f.i. Having a textField for email data in at least two different scenes and validate its format properly.
Having ViewControllers with so many business logic inside is not a good practice and we can easily end up having a large amount of code inside of our ViewController.
This piece of code is inside the ViewController class so if we had to implement another scene with emailTextField we would have a problem to reuse it.
Instead of doing this, we could have an extension of UITextField that handles UITextFieldDelegate functions so that each UITextField knows exactly how to validate itself and inside the UITextFieldDelegate functions we would only need to call that functions. Furthermore, in order to not to have the logic at this point, we can subclass UITextField with a new class EmailTextField that implements these new functions. Let’s see!
As you can see, we are extending UITextField class with UITextFieldDelegate functions so that the validation logic inside ViewController can be moved easily.
New EmailTextField Subclass
Now, to separate one validation logic from another we can create a new subclass EmailTextField that inherits from UITextField and implement these new functions.
If we see UITextField extension there are two functions that raise fatalError and the other one is empty. This is to ensure which functions should be mandatory and which should not. In this case, didBeginEditing can is optional and didEndEditing is mandatory (there is no reason to do that in one way or another but I wanted to show that too)
At this point we can update our previous ViewController to remove the validation logic that is now implemented in the subclasses of UITextField.
And last but not least… Our TextField Factory
If you are not using Storyboards, you are creating the views by code so it would be useful to implement the Factory pattern. With this, you can easily create different subclasses of UITextField.
As we’ve seen, it’s easy to have ViewControllers with many business logic and it’s not the best place to have it. Our app will be bigger and bigger and we could find many issues due to this fact. In software development, there is not one single solution to a problem and we must understand what is our problem in order to solve with a properly solution so I hope this can help you to have cleaner architectures and be aware of Single Responsibility Principle.