In my last post I talked about how to implement MVVM architecture for iOS. In this post I will explain how you can perform validation when using MVVM architecture for your iOS application.
We will work on a screen which will allow users to set new password. The screenshot below shows the user interface for the screen.
The change password screen is controlled by “ChangePasswordViewModel” which is implemented below:
Here are few validation rules we need to take into account.
- Password needs to be at least 8 characters long
- Passwords need to match
The ChangePasswordTableViewController utilizes the ChangePasswordViewModel to provide the data for the view. The directional binding from text field to view model properties is setup inside the view controller as shown below:
Whenever you change the values in text field the view model is automatically updated, containing the latest values from the text field. Now, we need to perform the actual validation. This can be implemented in view controller right inside the save action as shown below:
DON’T DO THAT!
You don’t want validation logic inside the view controller. This makes the view controller bloated with code that does not need to be there in the first place.
One way to solve this problem is to allow the view model to validate itself.
Ideally you would implement a validation engine class, whose responsibility is to validate the view models. Validation engine is an idol use case for custom attributes. Unfortunately, Swift currently does not support custom attributes.
Each broken rule will be represented by a BrokenRule class implemented below:
The ViewModel protocol defines the protocol which consists of brokenRules collection and isValid boolean property.
The ChangePasswordViewModel conforms to the ViewModel protocol and implements the validate function as shown below:
The validate functions performs all the validation. Again it would be nice to have a separate validation engine class which performs all the validation related tasks.
The isValid property resets the rules collection and then invokes the private validate function. Finally, it returns true or false depending if brokenRules list consists of any broken rules or not.
The view controller can now validate the view model using the following code:
Let’s test it out. Run the app and enter the following values for the new password and confirm password and try to save/update the password.
New Password = Leave it blank
Confirm Password = Leave it blank
The view model will be invalid and you will see the following message printed on the output window.
[Headlines.BrokenRule(propertyName: “newPassword”, message: “Password should be at least 8 characters long”)]
New Password = password123
Confirm Password = password345
[Headlines.BrokenRule(propertyName: “confirmPassword”, message: “Passwords are not matching”)]
I do hope that in the future version of Swift we can implement custom attributes. With custom attributes our view model will look as simple as shown below:
Obviously, you will still need to create the implementations for “Required” attribute but I believe it will remove a lot of unnecessary code from the view model. All the validation logic will be moved to ValidationEngine class which will dynamically validate the view model based on the decorated attributes and returns a list of broken rules.
You can download the code here:
Contribute to HeadlinesMVVM development by creating an account on GitHub.
On a separate note all of my courses on Udemy are on sale right now. You can grab a course for just $10. Check out the deal below: