A framework to validate inputs of text fields and text views in a convenient way.

Overview

License Build Status codecov.io Platform Swift Twitter

FormValidatorSwift

The FormValidatorSwift framework allows you to validate inputs of text fields and text views in a convenient way. It has been developed and used by iOS developers at ustwo.

Features

  • Simply use ValidatorTextField instead of UITextField or NSTextField (ValidatorTextView instead of UITextView or NSTextView)
  • Know what went wrong and where
  • Create own conditions using regular expressions for example
  • Create own validators which contain a collection of conditions
  • Support iOS, macOS, and tvOS

Dependencies

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate FormValidatorSwift into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.3'
use_frameworks!

pod 'FormValidatorSwift', '~> 3.0'

Then, run the following command:

$ pod install

Manually

If you prefer not to use either of the aforementioned dependency managers, you can integrate FormValidatorSwift into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
$ git init
  • Add FormValidatorSwift as a git submodule by running the following command:
$ git submodule add https://github.com/ustwo/formvalidator-swift.git
  • Open the new FormValidatorSwift folder, and drag the FormValidatorSwift.xcodeproj into the Project Navigator of your application's Xcode project.

    It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.

  • Select the FormValidatorSwift.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.

  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.

  • In the tab bar at the top of that window, open the "General" panel.

  • Click on the + button under the "Embedded Binaries" section.

  • You will see two different FormValidatorSwift.xcodeproj folders each with two different versions of the FormValidatorSwift.framework nested inside a Products folder.

    It does not matter which Products folder you choose from, but it does matter whether you choose the top or bottom FormValidatorSwift.framework.

  • Select the top FormValidatorSwift.framework for iOS, the middle one for tvOS, or the bottom one for macOS.

    You can verify which one you selected by inspecting the build log for your project. The build target for FormValidatorSwift will be listed as FormValidatorSwift iOS, FormValidatorSwift macOS, or FormValidatorSwift tvOS.

  • And that's it!

The FormValidatorSwift.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.


Usage

The two core components of FormValidatorSwift are Condition and Validator. These are both protocols, with many common implementations provided by the framework.

A Condition defines a specific requirement for a String to be considered valid and defines a way to check the String. A Validator defines a way to check whether a String is valid based on a set of Condition. These provide the building blocks upon which the other elements of FormValidatorSwift are built.

ValidatorTextField and ValidatorTextView provide common UI implementations for a validatable text input method. These controls can then be combined into a Form for quick validation of all text input.

Condition

A Condition is typically defined by a regular expression. This is used in the default implementation to check the string. However, you can provide your own implementation of the check(text:) function to do a more complicated validation.

Here is an example using one of the built-in conditions. Note that calling check(text:) simply returns a Bool as to whether the text is valid or not.

let condition = AlphanumericCondition()

let validResult = condition.check("Foo123")
let invalidResult = condition.check("Foo?!@")

Validator

A Validator takes an array of Condition and checks each condition to validate a string. If the validation fails, then checkConditions(text:) will return an array of the violated conditions.

Here is an example using one of the built-in validators. In this example, validResult will be nil and invalidResult will be [AlphanumericCondition].

let validator = AlphanumericValidator()

let validResult = validator.checkConditions("Foo123")
let invalidResult = validator.checkConditions("Foo?!@")

ValidatorTextField

To provide a user interface, you can use ValidatorTextField or ValidatorTextView. These are subclasses of UITextField and UITextView respectively (or NSTextField and NSTextView on macOS). They both conform to the ValidatorControl protocol, which has the additional capability of using a Validator to check the text.

Here is an example of a text field that would only allow alphanumeric text.

let nameTextField = ValidatorTextField(validator: AlphanumericValidator())

This does not work well for more complicated text fields. For example, you would not want an email address validated until the user is finished typing. To postpone validation, we need to set shouldAllowViolation and validateOnFocusLossOnly both to be true. Example:

let emailTextField = ValidatorTextField(validator: EmailValidator())
emailTextField.shouldAllowViolation = true
emailTextField.validateOnFocusLossOnly = true

We can respond to changes in the validity of ValidatorTextField by implementing the ValidatorControlDelegate and setting ourselves as the validator delegate (using the setValidatorDelegate(_:) method). Below is an example implementation. In the example we highlight the text field with a red border if it is invalid. We also list the error in a label called errorLabel and present it to the user.

func validatorControl(validatorControl: ValidatorControl, changedValidState validState: Bool) {
    guard let controlView = validatorControl as? UIView else {
        return
    }

    if validState {
        controlView.layer.borderColor = nil
        controlView.layer.borderWidth = 0.0
        errorLabel.hidden = true
    } else {
        controlView.layer.borderColor = UIColor.red.CGColor
        controlView.layer.borderWidth = 2.0
    }
}

func validatorControl(validatorControl: ValidatorControl, violatedConditions conditions: [Condition]) {
    var errorText = ""
    for condition in conditions {
        errorText += condition.localizedViolationString
    }
    errorLabel.text = errorText

    errorLabel.hidden = false
}

func validatorControlDidChange(validatorControl: ValidatorControl) {
    // Not used in this example
}

Form

We can combine a series of ValidatorControl into a Form. We have a convenience implementation call ControlForm. We can then combine our alphanumeric textfield and our email textfield from our previous examples into a form. This provides an easy method for checking if the entire form is valid (say, before submission of the form data to a server). Below is an example:

var form = ControlForm()

form.addEntry(nameTextField)
form.addEntry(emailTextField)

if form.isValid {
  // Hooray! Our form is valid. Submit the data!
  ...
} else {
  // Sad day, we need to have the user fix the data.
  ...
}

Example

More detailed examples can be found in the iOS Example and macOS Example apps in this repository.

Collaborate

We welcome contributors! Whether you're fixing a typo, squashing a bug, or adding new functionality please join us in making this project better. Read our contributing guidelines to find out how to add your support.

Maintainers

  • Shagun Madhikarmi (@madhikarma)
  • Aaron McTavish (@aamctustwo)

Contact

License

FormValidatorSwift is released under the MIT License. See the LICENSE file.

Comments
  • Add macOS Support

    Add macOS Support

    Resolves #25 Add macOS Support.

    Summary

    • Add macOS framework, unit test, example, and ui test targets
    • Add macOS (i.e. AppKit based) implementations of the validator controls
    • Updates UIKit validator controls to use more modern conventions
    • Update podspec for UIKit-based and AppKit-based targets (will update for v2.0 later when we merge v2 into master)
    • Updates Gem dependencies
    • Organise Example folder into iOS and macOS subfolders to separate out the source code

    Alternatives Considered

    I looked at using a common source file for both UIKit and AppKit implementations of UI controls and using a combination of typealiases and #if os() to separate the code. This become very messy quickly as the UIKit and AppKit implementations are sufficiently different.

    Instead, UIKit and AppKit specific files are suffixed as such in the file name (although the type name is common to allow some code portability). The podspec ignores the files based on the suffix, allowing for further expansion of framework dependent (and typically platform dependent) code in other areas of the FormValidator-Swift framework.

    Notes

    • Travis CI does not run the macOS UI Test Suite, it only builds it. This is due to an open issue. See https://github.com/travis-ci/travis-ci/issues/7075
    • Code coverage as reported by codecov.io has gone down with this PR as Xcode UI Tests from Travis to contribute to codecov.io metric for coverage and most of the new code in the framework is for UI controls. Nor are the macOS UI Tests run on Travis, as stated above. See https://github.com/codecov/example-swift/issues/16 for more details on the codecov.io side of the issue.
    opened by ghost 9
  • Support for Xcode 10, iOS 12, tvOS 12 and macOS 10.14 (Mojave).

    Support for Xcode 10, iOS 12, tvOS 12 and macOS 10.14 (Mojave).

    Summary

    Adds support for Xcode 10, iOS 12, tvOS 12 and macOS 10.14 (Mojave).

    Note

    • Updates CocoaPods to 1.6.0 Beta 1 do resolve an issue with pod lib lint using Xcode 10.
    opened by ghost 4
  • Feature/issue 43 fix should allow violation

    Feature/issue 43 fix should allow violation

    Summary

    This fixes ValidatorTextField and ValidatorTextView to behave correctly when the shouldAllowViolation property is set to true.

    This also changes ValidatorTextField and ValidatorTextView to initialize with a default of false for the shouldAllowViolation property. Doing this better matches the intent of the documentation.

    See issue #43 for more detail.

    opened by sparrowlegs 3
  • ValidatorTextField.shouldAllowViolation is behaving unexpectedly

    ValidatorTextField.shouldAllowViolation is behaving unexpectedly

    Description

    The ValidatorTextField incorrectly 'eats' characters when the shouldAllowViolation property is set false false.

    Steps to Reproduce

    1. In the iOS Example project. Change the nameEntry property in the FormView class to allow violations:
            nameEntry.textLabel.text = NSLocalizedString("Surname", comment: "")
            nameEntry.textField.shouldAllowViolation = true
            stackView.addArrangedSubview(nameEntry)
    
    1. Run the app and type the letter 'A' in the Surname field. So far, so good.
    2. Finally, type the number '1' in the Surname field.

    Expected Result

    The Surname field should contain the text 'A1' and be highlighted in red with the error text 'Enter letters only'.

    Actual Result

    The Surname field contains only text 'A' and no error state is indicated.

    Version Information

    The current version I am using is:

    • Xcode: 8.2.1 (8C1002)
    • iOS/tvOS: iPhone 7 simulator running iOS 10.2
    • FormValidator: 1.2.0

    Other Information

    I'm not sure if the following should be separate bugs. If you like, I can create them.

    With the shouldAllowViolation property set to true, an empty Surname field will allow the user to type one number. This shows the expected error state, but does not allow subsequent numbers to be typed.

    Also, with the single number in the Surname field, deleting this character does not return the field back to it's non-error state.

    bug 
    opened by sparrowlegs 3
  • Add Configuration Types

    Add Configuration Types

    Resolves #36 Update Conditions and Validators to Use Configs.

    Summary

    Adds configuration types for conditions and validators as appropriate.

    Details

    • Adds Configuration protocol
    • Adds ConfigurableCondition and ConfigurableValidator protocol
    • Updates Alphabetic, Alphanumeric, CreditCard, PasswordStrength, Postcode, and Range conditions and validators
    • Update Gem dependencies
    opened by ghost 2
  • Update Swiftlint to 0.14

    Update Swiftlint to 0.14

    Summary

    Update to support Swiftlint 0.14.

    Details

    • Removed disabled rules that did not cause issues
    • Added many opt-in rules to tighten listing
    • Removed excessive comments from .swiftlint.yml
    opened by ghost 2
  • Refactor PostcodeConditionTests

    Refactor PostcodeConditionTests

    Resolves #24 Refactor Postcode Tests.

    Summary

    Refactored PostcodeConditionTests.

    Details

    • Create extendible PostcodeConditionTests for when we add new countries
    • Add tests for United States post codes
    • Add test for changing countries in PostcodeCondition
    • Update PostcodeCountries to include allValues convenience var
    • Make PostcodeCountries.regex public
    • Alphabetise enumeration values.
    opened by ghost 2
  • Update Travis script to use `bundle exec`

    Update Travis script to use `bundle exec`

    Resolves #30 Fix Travis Script to Use Bundle Exec for Fastlane.

    Summary

    Adds bundle exec command when calling fastlane test to ensure we are using the correct version of Fastlane.

    opened by ghost 2
  • Can't assign validatorDelegate to ValidatorTextField

    Can't assign validatorDelegate to ValidatorTextField

    Description

    When I attempt to assign a validatorDelegate to a ValidatorTextField I get a compiler error: "Cannot assign to property: 'validatorDelegate' is a get-only property"

    Steps to Reproduce

    1. Create a ValidatorTextField.
    2. Assign validatorDelegate. field.validatorDelegate = self
    3. Xcode build error.

    Expected Result

    I should be able to assign my view controller as a delegate of the field.

    Actual Result

    Build error.

    Version Information

    The current version I am using is:

    • Xcode: 8.1
    • iOS/tvOS: 10.0
    • FormValidator: 1.0

    Other Information

    Add logs, screenshots, etc. that will help in debugging the issue.

    question 
    opened by nickfedoroff 2
  • Add Dangerfile

    Add Dangerfile

    Resolves #11 Add Dangerfile.

    Summary

    Adds a Dangerfile for PR linting.

    Details

    • Adds Dangerfile and adds danger command to Fastfile.
    • Adjust verify_demo lane to only build the demo app but not run UI Tests, as they have been flakey on Travis CI.
    • Update SwiftLint configuration (as it was using old rule names).

    Other Notes

    • Currently will not work with Forks due to using encrypted environment variables for Travis CI.
    opened by ghost 2
  • Minor gem updates

    Minor gem updates

    Summary

    Minor update to Ruby gem development dependencies to update mini-magick to resolve (CVE-2019-13574). This is a dependency of Fastlane, which we use for running our test suite and automating some of the release process.

    Larger updates are available for some of our gems, but this is not the purpose of this PR. It is meant to be a minimal update for some bug and vulnerability fixes.

    Note: This is a part of a dependency used for development of the framework and not a dependency of the framework itself.

    bug 
    opened by ghost 1
  • Add support for the new SwiftUI framework

    Add support for the new SwiftUI framework

    Description

    • Add support for the new SwiftUI framework

    Other Information

    • Dev docs: https://developer.apple.com/documentation/swiftui/
    • Dev tutorials: https://developer.apple.com/tutorials/swiftui/
    • Relevant WWDC sessions:
      • SwiftUI Essentials: https://developer.apple.com/videos/play/wwdc2019/216/
      • Data Flow Through SwiftUI: https://developer.apple.com/videos/play/wwdc2019/226
      • Building Custom Views with SwiftUI: https://developer.apple.com/videos/play/wwdc2019/237/
      • SwiftUI on All Devices: https://developer.apple.com/videos/play/wwdc2019/240/
      • Accessibility in SwiftUI: https://developer.apple.com/videos/play/wwdc2019/238/
    • Related to #82 Add support for the new Combine framework
    enhancement 
    opened by ghost 0
  • Add support for the new Combine framework

    Add support for the new Combine framework

    Description

    Add support for the new Combine framework.

    Other information

    • Dev docs: https://developer.apple.com/documentation/combine
    • Relevant WWDC sessions:
      • Introducing Combine: https://developer.apple.com/videos/play/wwdc2019/722/
      • Combine in Practice: https://developer.apple.com/videos/play/wwdc2019/721/
      • Data Flow Through SwiftUI: https://developer.apple.com/videos/play/wwdc2019/226
    enhancement 
    opened by ghost 0
  • Allow for initialising validator with localizedViolationString

    Allow for initialising validator with localizedViolationString

    It would be nice if it were easier to update the localizedViolationString when initialising a violation object.

    For example I currently have an extension on Validator which allows me to initialise with a violationString.

    extension Validator {
        public init(violationString: String) {
            self.init()
            var condition = self.conditions.first!
            condition.localizedViolationString = violationString
            conditions = [condition]
        }
    }
    

    Which makes creating a form much easier when I have multiple strings per field:

    self.controlForm.addField(passwordTextField, validator: PresentValidator(violationString: "Please enter your password"))
    
    enhancement 
    opened by markst 2
  • ValidatorControlDelegate is only possible when using `ValidatorTextField`

    ValidatorControlDelegate is only possible when using `ValidatorTextField`

    I use https://github.com/CosmicMind/Material Which has it's own styled UITextField subclasses.

    My subclassed text field implements ValidatorControl protocol.

    class ValidationTextField: ErrorTextField, ValidatorControl
    

    It would be good if I could use ValidatorControlDelegate when using other classes besides the provided ValidatorTextField.

    question 
    opened by markst 5
  • Automate Release Process

    Automate Release Process

    Description

    Automate the release process.

    Details

    Automate releasing a new version of the framework using Fastlane.

    This could include, but not limited to:

    • [x] Version Bump
    • [x] Git Tag
    • [x] Update Documentation
    • [ ] Podspec Update & Release
    enhancement blocked 
    opened by ghost 2
  • Update `EmailCondition` to Support Unicode

    Update `EmailCondition` to Support Unicode

    Description

    Update EmailCondition and EmailValidator to include support for Unicode per RFC 6530 as an option.

    Notes

    • See also issue #28 Option to allow unicode for AlphabeticValidator.
    enhancement 
    opened by ghost 0
Releases(4.0.0)
  • 4.0.0(Apr 24, 2019)

  • 3.2.0(Apr 25, 2018)

  • 3.1.0(Apr 4, 2018)

    Breaking
    • None.
    Added
    • Added Xcode 9.3 support.
    Updated
    • Removes weak on property in ValidatorControl protocol as it is now deprecated in the latest version of Swift. See: https://github.com/apple/swift-evolution/pull/707
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Feb 8, 2018)

  • 2.0.0(Feb 6, 2017)

    Breaking

    • Updated AlphabeticCondition and AlphanumericCondition to allow unicode characters by default (NumericCondition already allowed unicode characters by default).
    • AlphabeticCondition, AlphanumericCondition, CreditCardCondition, NumericCondition, PasswordStrengthCondition, PostcodeCondition, and RangeCondition now store their configurations in a configuration property rather than as top-level properties of the condition's instance. As an example, for an instance of AlphabeticCondition the check condition.allowsWhitespace == true would become condition.configuration.allowsWhitespace == true.

    Added

    • Added Configuration, ConfigurableCondition, ConfigurableValidator protocols. Updated existing conditions and validators to take advantage of new protocols.
    • Added macOS support.

    Updated

    • NumericCondition now supports ASCII only (as opposed to allowing any Unicode numeric characters) as an option. The default remains allowing Unicode characters.
    • The shouldAllowViolation property on validator controls now works as expected.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Dec 21, 2016)

  • 1.1.0(Dec 5, 2016)

  • 1.0.0(Oct 17, 2016)

Owner
ustwo™
Our purpose is to inspire and unleash the collective genius of our people, our clients, and our partners.
ustwo™
Validate that apple-app-site-association files are set up correctly

SwiftAASAValidator Validate that apple-app-site-association files are set up correctly The idea is you can use these functions in your test suite for

Ben Spratling IV 1 Apr 12, 2022
The most flexible and powerful way to build a form on iOS

The most flexible and powerful way to build a form on iOS. Form came out from our need to have a form that could share logic between our iOS apps and

HyperRedink 32 Aug 15, 2022
A UITableViewCell with an editable text field

FDTextFieldTableViewCell Features Fully featured like the Right Detail style Adds a UITextField to the cell and places it correctly Usage Select a cel

William Entriken 26 May 30, 2022
TCDInputView is an open source custom input view which is displayed when a text field becomes the first responder.

TCDInputView for iOS TCDInputView is an open source custom input view which is displayed when a text field becomes the first responder. Requirements T

Tom Diggle 7 Apr 25, 2016
SwiftyFORM is a lightweight iOS framework for creating forms

SwiftyFORM is a lightweight iOS framework for creating forms Because form code is hard to write, hard to read, hard to reason about. Has a

Simon Strandgaard 1.1k Dec 29, 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
Declarative data validation framework, written in Swift

Peppermint Introduction Requirements Installation Swift Package Manager Usage Examples Predicates Constraints Predicate Constraint Compound Constraint

iOS NSAgora 43 Nov 22, 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
Carbon🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.

A declarative library for building component-based user interfaces in UITableView and UICollectionView. Declarative Component-Based Non-Destructive Pr

Ryo Aoyama 1.2k Jan 5, 2023
SwiftForms is a small and lightweight library written in Swift that allows you to easily create forms.

SwiftForms is a powerful and extremely flexible library written in Swift that allows to create forms by just defining them in a couple of lines. It also provides the ability to customize cells appearance, use custom cells and define your own selector controllers.

Miguel Ángel Ortuño 1.3k Dec 27, 2022
XLForm is the most flexible and powerful iOS library to create dynamic table-view forms. Fully compatible with Swift & Obj-C.

XLForm By XMARTLABS. If you are working in Swift then you should have a look at Eureka, a complete re-design of XLForm in Swift and with more features

xmartlabs 5.8k Jan 6, 2023
Discover new programming concepts and more new SwiftUI 2 features in this section

Africa-Zoo One thing is sure, we will discover new programming concepts and more new SwiftUI 2 features in this section. TOPICS ARE COVERED: JSON with

Noye Samuel 2 Nov 8, 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
A framework to validate inputs of text fields and text views in a convenient way.

FormValidatorSwift The FormValidatorSwift framework allows you to validate inputs of text fields and text views in a convenient way. It has been devel

ustwo™ 500 Nov 29, 2022
A drop-in universal solution for moving text fields out of the way of the keyboard in iOS

TPKeyboardAvoiding A drop-in universal solution for moving text fields out of the way of the keyboard in iOS. Introduction There are a hundred and one

Michael Tyson 5.8k Dec 26, 2022
Add validations to your text fields, Group them together and navigate through them via keyboard's return button and accessory view.

TFManager Let's say you have multiple UITextFields to get data from users. You need to handle each field keyboard's return key and add an accessory vi

Hosein Abbaspour 16 Sep 29, 2022
Define and chain Closures with Inputs and Outputs

Closure Define and chain Closures with Inputs and Outputs Examples No Scoped State let noStateCount = Closure<String, String> { text in String(repea

Zach Eriksen 3 May 18, 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
UITextField and UITextView subclasses with placeholders that change into floating labels when the fields are populated with text.

Deprecated Please use JVFloatLabeledTextField instead or feel free to chime in on an issue if you'd like to take over the repo. RPFloatingPlaceholders

rob phillips 1.1k Jan 5, 2023
Lightweight set of text fields with nice animation and functionality

TweeTextField This is lightweight library that provides different types of Text Fields based on your needs. I was inspired by Jan Henneberg. Features

Oleg 471 Nov 10, 2022