Validation Handling in Swift 3.0

 

User experience is the key factor for any application. Thus, More the developer is capable of delivering help, higher is the user experience. It is a mandatory for almost every application to include sign up forms,()……etc. Hence, pops up the point of validation to all these fields.

Consider a Sign up form consisting of following textfields:

  • Email
  • Name
  • Mobile no.
  • Maximum ten characters password
  • Alpha numeric field
  • Or it can be any field according to your requirement.

There can be as many approaches you could follow to validate your set of textfields. One can do all the validations on same view controller which results in a high complexity of code. But not to worry. You are at a right place to get your set of textfields validated. Continue reading to get an approach which is much more easier to implement with no more code complexity.

How ValidationManager works?

The image below showing how ValidationManager in Swift 3.0 works independently of a particular view controller.

Screen Shot 2017-02-10 at 11.34.47 AM

Steps:

  1. View Controller sends textfields inputs to the struct/class named FormvalidationModel.
  2. All the textfields input is bundles into FormValidationModel object and returns to the calling View controller.
  3. View Controller sends this FormValidationModel object to the ValidationManager for validation.
  4. If any error occurs like a field is empty or failed by the regular expression, ValidationManager sends error code and error message to the struct/class named ValidationError.
  5. The error code and error message is bundled into a ValidationError object and returns to the ValidationManager.
  6. The ValidationManager returns the ValidationError object to the View Controller.
  7. View Controller shows the validation failure if validationError contains any error message and error code in the form of alert or toast as per the requirement else the form doesn’t contain any error and is ready to be Submit which is great.

Here’s shown an example below:

Simulator Screen Shot 08-Feb-2017, 4.58.25 PM

  1. On clicking Submit button after adding values to the textfields in the set of textfields for ex- signUpForm in our case, create an instance of validation model for ex- FormValidationModel and add values of the textfields to the model in your view Controller.
  2. Pass this model as a parameter to the ValidationManager by calling validateForm(signUpModel: FormValidationModel) function and assign the value return by this function to a variable.
  3. This method returns an instance of ValidationError which contains either nil or error values such as ErrorCode and ErrorMessage.
  4. Handle this validation failure on your view controller as per the requirement.

FormValidationModel.Swift

To add this approach to your project, first of all create a swift file with name FormValidationModel following the steps below:

  • Project name folder > New File > Swift File
  • Enter name in save as field as FormValidationModel
  • Click on Create

Now open the newly created FormValidationModel class and add the code below to your file:

struct FormValidationModel {

   //Code
}

complete the above code by adding the following:

struct FormValidationModel {

    // MARK:- VARIABLES
    var email: String?
    var name: String?
    var mobileNo: String?
    
    //MARK:- CONSTRUCTORS
    
    init(userEmail: String?, userName: String, mobile: String) {
        
        email = userEmail
        name = userName
        mobileNo = mobile
    }
}

Here we ends up with creating a FormValidationModel.Swift. The declared parameters are used to store the values of the textfields, where these values are needed to be validated further.

Now to create FormValidationModel instance, pass all the textfield’s(which needs to be validated) text as a parameter to the constructor init() of the FormValidationModel struct.

ValidationError.Swift

Create a swift file with name ValidationError and open the newly created ValidationError file to add the code below:

struct ValidationError {
    
    var errorCode: Int!
    var errorString: String!
    
    init(code: Int, message: String) {
        
        errorCode = code
        errorString = message
    }
    
    struct ErrorCodes {
        
        static let errorCodeEmptyText = 3003
        static let errorCodeInvalidAlphaNumericTest = 3006
        static let errorCodeInvalidMobileNo = 3008
        static let errorCodeMaxLengthExceed = 3009
        static let errorCodeInvalidName = 3010
        static let errorCodeInvalidEmail = 3004
    }
    
    struct ErrorMessages {
        
        static let msgEmptyEmail = "Please enter your Email Address"
        static let msgInvalidEmail = "Please enter a valid Email Address"
        static let msgEmptyName = "Please enter your Name"
        static let msgInvalidAlphaNumericTest = "Please enter a valid AlphaNumeric Text"
        static let msgEmptyMobileNo = "Please enter mobile Number"
        static let msgInvalidMobileNo = "Please enter a valid mobile number"
        static let msgLimitedText = "Please enter text upto the specified limit"
        static let msgInvalidName = "Please enter a valid Name"
        static let msgEmptyText = "Please enter the text"
    }
}

This file contains all the error codes and error messages we need to show on validation failures on main view controller. You can add many more error codes and error messages according to your requirement.

The constructor of the ValidationError is called every time the string validation failure occurs which accepts two parameters naming errorCode and errorMessage and returns the ValidationError model which is to be passed to the view controller by the ValidationMananger. The view controller receives either the ValidationModel with error messages and error codes or nil. If validationError is nil that means the string validation is passed else the string validation is failed and hence we need to show the validation failure through toast or alert as per the requirement.

ValidationManager.Swift

Now create a swift file with name ValidationManager and open the newly created ValidationManager file to add the code below:

static private let regexEmail = "[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}"
static private let regexMobNo = "^[0-9]{6,15}$"
static private let regexNameType = "^[a-zA-Z]+$"

The above code declares the regex string which check if the input string satisfies the regular expression or not. You can add more regex according to your requirement.

Now add the code below to your validationManager file just after the regular expression declaration:

static func validateForm(signUpModel: FormValidationModel) -> ValidationError? {
        
        var validationError: ValidationError? = nil
        validationError = validateEmailId(email: signUpModel.email!)
        if validationError != nil {
            
            return validationError
        }
        
        validationError = validateNameString(string: signUpModel.name!)
        if validationError != nil {
            
            return validationError
        }
        
        validationError = validateMobileNumber(string: signUpModel.mobileNo!)
        if validationError != nil {
            
            return validationError
        }
    }

This method accepts a valid FormValidationModel as a parameter and is called from your view controller containing the set of textfields.

Now add the following methods below the validateForm() method to validate different fields:

//MARK: validate emailID
    
    private static func validateEmailId(email: String) -> ValidationError?
    {
        var validationError : ValidationError? = nil
        
        if email == ""
        {
            validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeEmptyText, message: ValidationError.ErrorMessages.msgEmptyEmail)
        }
        else {
            let emailTest = NSPredicate(format: stringSelfMatch, regexEmail)
            let matchEmailId = emailTest.evaluate(with: email)
            if(!matchEmailId)
            {
                validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeInvalidEmail, message: ValidationError.ErrorMessages.msgInvalidEmail)
            }
        }
        return validationError
    }
    
    //MARK: validate Mobile number
    
    private static func validateMobileNumber(string: String) -> ValidationError?
    {
        var validationError : ValidationError? = nil
        if string == "" {
            validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeEmptyText, message: ValidationError.ErrorMessages.msgEmptyMobileNo)
        }
        else {
            
            let mobileNoTest = NSPredicate(format: stringSelfMatch, regexMobNo)
            let matchMobileNumber = mobileNoTest.evaluate(with: string)
            if(!matchMobileNumber)
            {
                validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeInvalidMobileNo, message: ValidationError.ErrorMessages.msgInvalidMobileNo)
            }
        }
        return validationError
    }
    
    //MARK: validate name
    
    private static func validateNameString(string: String) -> ValidationError?
    {
        var validationError : ValidationError? = nil
        if string == "" {
            validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeEmptyText, message: ValidationError.ErrorMessages.msgEmptyName)
        }
        else {
            
            let nameTest = NSPredicate(format: stringSelfMatch, regexNameType)
            let matchNameType = nameTest.evaluate(with: string)
            if !matchNameType
            {
                validationError = ValidationError(code: ValidationError.ErrorCodes.errorCodeInvalidName, message: ValidationError.ErrorMessages.msgInvalidName)
            }
        }
        return validationError
    }

You can add as many methods as you need in this Manager.

This completes the ValidationManager implemented in Swift 3.0 which can be used from any view controller where textfield validation is required.

Leave a Reply