Declarative form validator for SwiftUI.

Overview

Gray shape shifter

SwiftUIFormValidator

The world's easiest, most clean SwiftUI form validation.



Stargazers repo roster for @ShabanKamell/SwiftUIFormValidator

SwiftUIFormValidator

A declarative SwiftUI form validation. Clean, simple, and customizable.

Discuss it on Product Hunt 🦄

Form Screenshot

Table of contents

Usage

Basic Setup

  // 1 
import FormValidator

// 2
class FormInfo: ObservableObject {
    @Published var firstName: String = ""
    // 3
    lazy var form = {
        FormValidation(validationType: .immediate)
    }()
    // 4
    lazy var firstNameValidation: ValidationContainer = {
        $firstName.nonEmptyValidator(form: form, errorMessage: "First name is not valid")
    }()
}

struct ContentView: View {
    // 5
    @ObservedObject var formInfo = FormInfo()

    var body: some View {
        TextField("First Name", text: $formInfo.firstName)
                .validation(formInfo.firstNameValidation) // 6
    }
}
  1. Import FormValidator.
  2. Declare an ObservableObject for the form with any name, for example, FormInfo, LoginInfo, or any name.
  3. Declare FormValidation object and choose a validation type.
  4. Declare a ValidationContainer for the field you need to validate.
  5. In your view, declare the FormValidation object.
  6. Declare validation(formInfo.firstNameValidation) with the validation of the field.

Congratulation!! your field is now validated for you!

Inline Validation

For fast validation, you can use InlineValidator and provide your validation logic in line:

 lazy var lastNamesValidation: ValidationContainer = {
    $lastNames.inlineValidator(form: form) { value in
        // Put validation logic here
        !value.isEmpty
    }
}()

Validation Types

You can choose between 2 different validation types: FormValidation(validationType: .immediate) and FormValidation(validationType: .deffered)

  1. immediate: the validation is triggered every time the field is changed. An error message will be shown in case the value is invalid.
  2. deferred: in this case, the validation will be triggered manually only using FormValidation.triggerValidation() The error messages will be displayed only after triggering the validation manually.

Manual Validation

You can trigger the form validation any time by calling FormValidation.triggerValidation(). After the validation, each field in the form will display error message if it's invalid.

React to Validation Change

You can react to validation change using FormValidation.$allValid and FormValidation.$validationMessages

VStack {
} // parent view of the form
        .onReceive(formInfo.form.$allValid) { isValid in
            self.isSaveDisabled = !isValid
        }
        .onReceive(formInfo.form.$validationMessages) { messages in
            print(messages)
        }

🎉 Installation

CocoaPods

Use the following entry in your Podfile:

pod 'SwiftUIFormValidator'

Then run pod install.

Swift Package Manager

Add the following as a dependency to your Package.swift:

.package(url: "https://github.com/ShabanKamell/SwiftUIFormValidator.git")

and then specify "SwiftUIFormValidator" as a dependency of the Target in which you wish to use SwiftUIFormValidator. Here's an example PackageDescription:

// swift-tools-version:5.1

import PackageDescription

let package = Package(
        name: "MyPackage",
        products: [
            .library(
                    name: "MyPackage",
                    targets: ["MyPackage"]),
        ],
        dependencies: [
            .package(url: "https://github.com/ShabanKamell/SwiftUIFormValidator")
        ],
        targets: [
            .target(
                    name: "MyPackage",
                    dependencies: ["SwiftUIFormValidator"])
        ]
)

Accio

Accio is a dependency manager based on SwiftPM which can build frameworks for iOS/macOS/tvOS/watchOS. Therefore the integration steps of SwiftUIFormValidator are exactly the same as described above. Once your Package.swift file is configured, run accio update instead of swift package update.

Don't forget to add import FormValidator to use the framework.

Carthage

Carthage users can point to this repository and use generated SwiftUIFormValidator framework.

Make the following entry in your Cartfile:

github "ShabanKamell/SwiftUIFormValidator"

Then run carthage update.

If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained over at Carthage.

Validators

Validator Description
NonEmptyValidator Validates if a string is empty or blank
EmailValidator Validates if the email is valid.
DateValidator Validates if a date falls within after & before dates.
PatternValidator Validates if a patten is matched.
InlineValidator Validates if a condition is valid.
PasswordValidator Validates if a password is valid.
PrefixValidator Validates if the text has a prefix.
SuffixValidator Validates if the text has a suffix.

Custom Validators

In easy steps, you can add a custom validator:

// 1
public class NonEmptyValidator: StringValidator {
    public var publisher: ValidationPublisher!
    public var subject: ValidationSubject = .init()
    public var onChanged: ((Validation) -> Void)? = nil

    public var errorMessage: StringProducerClosure = {
        ""
    }
    public var value: String = ""

    public func validate() -> Validation {
        if value.trimmingCharacters(in: .whitespaces).isEmpty {
            return .failure(message: errorMessage())
        }
        return .success
    }
}

// 2
extension Published.Publisher where Value == String {
    func nonEmptyValidator(
            form: FormValidation,
            errorMessage: @autoclosure @escaping StringProducerClosure = ""
    ) -> ValidationContainer {
        let validator = NonEmptyValidator()
        let message = errorMessage()
        return ValidationPublishers.create(
                form: form,
                validator: validator,
                for: self.eraseToAnyPublisher(),
                errorMessage: !message.isEmpty ? message : form.messages.required)
    }
}
  1. Implement FormValidator protocol.
  2. Add the validator logic in an extension to Published.Publisher.

Note

NonEmptyValidator is a built-in validator in the library.

Validation Messages

You can provide a validation message for every field by providing errorMessage

$firstName.nonEmptyValidator(form: form, errorMessage: "First name is not valid")

If you don't provide a message, a default one will be used for built-in providers. All default messages are located in DefaultValidationMessages class.

$firstName.nonEmptyValidator(form: form) // will use the default message

In this example, DefaultValidationMessages.required will be used.

Overriding Default Validation Messages

You can override the default validation messages by inheriting from DefaultValidationMessages

class ValidationMessages: DefaultValidationMessages {
    public override var required: String {
        "Required field"
    }
    // Override any message ...
}

Or if you need to override all the messages, you can implement ValidationMessagesProtocol.

And provide the messages to FormValidation

FormValidation(validationType: .immediate, messages: ValidationMessages())

Credit

Validation with SwiftUI & Combine

👏 Contribution

All Pull Requests (PRs) are welcome. Help us make this library better.

Changelog

Look at Changelog for release notes.

License

click to reveal License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • View Handling it's own validation UI

    View Handling it's own validation UI

    Hi There

    Thanks for sharing a great project. Would it be possible to allow a view to handle its own validation UI via a binding instead of putting an error message underneath view via the viewmodifier? For my use case I would like to change the text colour of the input and apply a red stroke around it in addition to showing the error message underneath.

    Thanks!

    opened by chriskilpin 2
  • Feature Request: validation view modifier that accepts nil

    Feature Request: validation view modifier that accepts nil

    It would be awesome if the validation view modifier accepted nil for conditional validation could be used...

    e.g.

    suggestion

    I have common functionality where I'd like to use this

    opened by JulesMoorhouse 1
  • Invalid Exclude - 2 files not found

    Invalid Exclude - 2 files not found

    Invalid Exclude '/Users/me/Library/Developer/Xcode/DerivedData/snip/SourcePackages/checkouts/
    SwiftUIFormValidator/Sources/Examples': File not found.
    
    Invalid Exclude '/Users/me/Library/Developer/Xcode/DerivedData/snip/SourcePackages/
    checkouts/SwiftUIFormValidator/Sources/Tests': File not found.
    

    I've added the package and I'm getting these warnings...

    I'm using Xcode 13.2.1

    I think it's just that the Sources folder isn't required.. Tests and Examples appear in the parent folder.

    Best regards,

    Jules.

    opened by JulesMoorhouse 1
  • Hi error messages not showing

    Hi error messages not showing

    I added an array of validations how is it:

    lazy var firstNameValidation: ValidationContainer = {
            let validators: [StringValidator] = [
                CountValidator(count: 6, type: .greaterThanOrEquals),
                PrefixValidator(prefix: "st.")
            ]
            return $username.allValid(validators: validators, form: form)
        }()
    

    and run manual trigger validation, then the message error not show

    form.triggerValidation()

    my form @Published var form = FormValidation(validationType: .immediate)

    only show error when value changed

    opened by danieldflrss 1
  • Update minimum macOS version to `10_15`.

    Update minimum macOS version to `10_15`.

    Attempting to build this package for macOS throws a number of compiler errors due to Published only being available on 10.15 and up.

    Bumping the version in Package.swift appears to resolve this.

    published-error
    opened by CypherPoet 0
  • The following build commands failed: PhaseScriptExecution

    The following build commands failed: PhaseScriptExecution

    Hi, I'm facing an error while using the SwiftUIFormValidator library during Azure DevOp Pipeline building process.

    I'm currently developing an app using Kotlin MultiPlatform Mobile.

    I'm using SwiftUIFormValidator for form validations in iOS.

    I'm able to build it successfully in local machine but not in Azure DevOps Pipeline.

    Here's the error log.

    Running script '[CP-User] Build shared' ▸ Processing SwiftUIFormValidator-Info.plist ** BUILD FAILED **

    The following build commands failed: PhaseScriptExecution [CP-User]\ Build\ shared /Users/runner/Library/Developer/Xcode/DerivedData/iosApp-dongzyrxhgtfzxexzqjllvyjwgcu/Build/Intermediates.noindex/Pods.build/Release-iphoneos/shared.build/Script-4552119A071AC6BAB7327E6434237EC3.sh (in target 'shared' from project 'Pods')

    Kindly let me know the solution for the above error. Thank you.

    opened by keerthankrrao 0
  • How to get localized validation messages?

    How to get localized validation messages?

    I'm trying to setup a multilingual app with Localizable.strings. So far, the UI elements in SwiftUI all translate as expected. How do we get the validation messages to translate accordingly?

    opened by jonsaw 1
Releases(0.18.1)
Owner
Shaban Kamel
Mobile Software Engineer, 5 years of experience in mobile development.
Shaban Kamel
SwiftEmailValidator - A Swift implementation of an international email address syntax validator based on RFC5321 & RFC5322

SwiftEmailValidator A Swift implementation of an international email address syn

Dave Poirier 21 Oct 24, 2022
iOS validation framework with form validation support

ATGValidator ATGValidator is a validation framework written to address most common issues faced while verifying user input data. You can use it to val

null 51 Oct 19, 2022
🚦 Validation library depends on SwiftUI & Combine. Reactive and fully customizable.

?? Validation library depends on SwiftUI & Combine. Reactive and fully customizable.

Alexo 14 Dec 30, 2022
Declarative form building framework for iOS

Formalist Swift framework for building forms on iOS Formalist is a Swift framework for building forms on iOS using a simple, declarative, and readable

Seed 159 May 25, 2022
Swift Validator is a rule-based validation library for Swift.

Swift Validator is a rule-based validation library for Swift. Core Concepts UITextField + [Rule] + (and optional error UILabel) go into

null 1.4k Dec 29, 2022
A Payment Card UI & Validator for iOS

Description Caishen provides an easy-to-use text field to ask users for payment card information and to validate the input. It serves a similar purpos

Prolific Interactive 766 Dec 28, 2022
Swift String Validator. Simple lib for ios to validate string and UITextFields text for some criterias

Swift String validator About Library for easy and fastest string validation based on сciterias. Instalation KKStringValidator is available through Coc

Kostya 17 Dec 21, 2019
A validator for postal codes with support for 200+ regions

PostalCodeValidator A validator for postal codes with support for 200+ regions. import Foundation import PostalCodeValidator if let validator = Posta

FormatterKit 211 Jun 17, 2022
SwiftEmailValidator - A Swift implementation of an international email address syntax validator based on RFC5321 & RFC5322

SwiftEmailValidator A Swift implementation of an international email address syn

Dave Poirier 21 Oct 24, 2022
Focus text field in SwiftUI dynamically and progress through form using iOS keyboard.

Focuser Focuser allows to focus SwiftUI text fields dynamically and implements ability move go through the form using Keyboard for iOS 13 and iOS 14.

Art Technologies 118 Dec 25, 2022
SherlockForms - An elegant SwiftUI Form builder to create a searchable Settings and DebugMenu screens for iOS

??️‍♂️ SherlockForms What one man can invent Settings UI, another can discover i

Yasuhiro Inami 98 Dec 27, 2022
ReadabilityModifier - UIKits readableContentGuide for every SwiftUI View, in the form of a ViewModifier

ReadabilityModifier UIKits readableContentGuide for every SwiftUI View, in the form of a ViewModifier What it is Displaying multiple lines of text in

YAZIO 15 Dec 23, 2022
nef💊a toolset to ease the creation of documentation in the form of Xcode Playgrounds

nef, short for Nefertiti, mother of Ankhesenamun, is a toolset to ease the creation of documentation in the form of Xcode Playgrounds. It provides com

Bow 257 Dec 6, 2022
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
MZFormSheetPresentationController provides an alternative to the native iOS UIModalPresentationFormSheet, adding support for iPhone and additional opportunities to setup UIPresentationController size and feel form sheet.

MZFormSheetPresentationController MZFormSheetPresentationController provides an alternative to the native iOS UIModalPresentationFormSheet, adding sup

Michał Zaborowski 979 Nov 17, 2022
Elegant iOS form builder in Swift

Made with ❤️ by XMARTLABS. This is the re-creation of XLForm in Swift. 简体中文 Overview Contents Requirements Usage How to create a Form Getting row valu

xmartlabs 11.6k Jan 1, 2023
Former is a fully customizable Swift library for easy creating UITableView based form.

Former is a fully customizable Swift library for easy creating UITableView based form. Submitting Issues Click HERE to get started with filing a bug r

Ryo Aoyama 1.3k Dec 27, 2022
ObjectForm - a simple yet powerful library to build form for your class models.

ObjectForm A simple yet powerful library to build form for your class models. Motivations I found most form libraries for swift are too complicated to

jakehao 175 Nov 2, 2022
iOS validation framework with form validation support

ATGValidator ATGValidator is a validation framework written to address most common issues faced while verifying user input data. You can use it to val

null 51 Oct 19, 2022
ALO sync allows you to sync resources form an ALO endpoint to your macOS file system.

ALO sync allows you to sync resources form an ALO endpoint to your macOS file system. Prerequisites macOS 11 No support for search* No suppor

Lawrence Bensaid 2 Jan 22, 2022