Validator: A modular, type-safe validation framework for SwiftUI and UIKit

Hello Swift community :waving_hand:

Iโ€™d like to introduce Validator, a modern and lightweight Swift framework designed to make input validation elegant, type-safe, and painless. Whether you are building a complex registration form or a simple search bar, Validator provides a unified way to handle data integrity across all Apple platforms.

The philosophy behind Validator is straightforward:

Validation logic should be declarative, reusable, and decoupled from your business logic, while remaining deeply integrated with the UI frameworks we use every day.

Motivation

In many Swift projects, especially those with heavy user input, validation often becomes a mess of:

  • Manual string checks inside ViewControllers or SwiftUI Views.

  • Duplicated Regex patterns scattered everywhere.

  • Inconsistent error handling between UIKit and SwiftUI.

  • Hard-to-test conditional logic.

Validator solves this by providing a robust core engine and specialized UI extensions that feel native to both imperative and declarative styles.

Architecture

The framework is intentionally split into two libraries to keep your targets lean and separate concerns:

  • ValidatorCore: The engine of the package. It encompasses all core validation logic, the IValidationRule protocol, and a comprehensive set of predefined validators. It has no dependencies on UI frameworks, making it perfect for Unit Testing or use in CLI tools/Services.

  • ValidatorUI: A layer built on top of the core. It implements extensions and logic specifically for interacting with UI components, providing a seamless experience for both UIKit and SwiftUI.

Integration

One of Validator's strongest points is its support for both UIKit and SwiftUI, separated into two logical modules: ValidatorCore and ValidatorUI.

UIKit Support

Import ValidatorUI to add validation to UITextField without the boilerplate of delegates. It supports real-time validation and custom handlers.

// Enable real-time validation on change
emailField.validateOnInputChange(isEnabled: true)

emailField.add(
    rule: EmailValidationRule(error: "Please enter a valid email")
)

emailField.validationHandler = { result in
    // Update your UI based on .valid or .invalid(errors)
}

SwiftUI Support

For SwiftUI, Validator uses property wrappers and modifiers that fit perfectly into the declarative state-driven flow.

@FormField(rules: [LengthValidationRule(min: 8, error: "Too short")])
var password = ""

// In your body
TextField("Password", text: $password)
    .validate(item: $password) { errors in
        ForEach(errors, id: \.message) { error in
            Text(error.message).foregroundColor(.red)
        }
    }

Predefined Rules

You donโ€™t have to reinvent the wheel. Validator comes packed with a rich set of built-in rules covering almost every common scenario:

Rule Description Example
LengthValidationRule Validates string length (min/max) LengthValidationRule(min: 3, max: 20, error: "Length must be 3-20 characters")
NonEmptyValidationRule Ensures string is not empty or blank NonEmptyValidationRule(error: "Field is required")
PrefixValidationRule Validates string prefix PrefixValidationRule(prefix: "https://", error: "URL must start with https://")
SuffixValidationRule Validates string suffix SuffixValidationRule(suffix: ".com", error: "Domain must end with .com")
RegexValidationRule Pattern matching validation RegexValidationRule(pattern: "^\\d{3}-\\d{4}$", error: "Invalid phone format")
URLValidationRule Validates URL format URLValidationRule(error: "Please enter a valid URL")
CreditCardValidationRule Validates credit card numbers (Luhn algorithm) CreditCardValidationRule(error: "Invalid card number")
EmailValidationRule Validates email format EmailValidationRule(error: "Please enter a valid email")
CharactersValidationRule Validates that a string contains only characters from the allowed CharacterSet CharactersValidationRule(characterSet: .letters, error: "Invalid characters")
NilValidationRule Validates that value is nil NilValidationRule(error: "Value must be nil")
PositiveNumberValidationRule Validates that value is positive PositiveNumberValidationRule(error: "Value must be positive")
NoWhitespaceValidationRule Validates that a string does not contain any whitespace characters NoWhitespaceValidationRule(error: "Spaces are not allowed")
ContainsValidationRule Validates that a string contains a specific substring ContainsValidationRule(substring: "@", error: "Must contain @")
EqualityValidationRule Validates that the input is equal to a given reference value EqualityValidationRule(compareTo: password, error: "Passwords do not match")
ComparisonValidationRule Validates that input against a comparison constraint ComparisonValidationRule(greaterThan: 0, error: "Must be greater than 0")
IBANValidationRule Validates that a string is a valid IBAN (International Bank Account Number) IBANValidationRule(error: "Invalid IBAN")
IPAddressValidationRule Validates that a string is a valid IPv4 or IPv6 address IPAddressValidationRule(version: .v4, error: ValidationError("Invalid IPv4"))
PostalCodeValidationRule Validates postal/ZIP codes for different countries PostalCodeValidationRule(country: .uk, error: "Invalid post code")

Documentation

The documentation is designed to get you up and running in minutes. It covers everything from basic single-field validation to complex FormFieldManager setups for multi-step forms.

You can find the full guide here: Validator Documentation

Repository

Validator is fully open-source and has zero external dependencies. It is built with Swift 5.10+ and supports iOS 16+, macOS 13+, and even visionOS. Welcome contributions, whether it's a new validation rule, a bug fix, or a suggestion for the UI API.

Repository link: https://github.com/space-code/validator

If Validator helps you clean up your form logic, please consider giving the repo a :star:. It helps others find the project!

Thanks for taking the time to check it out!

1 Like