GithubHelp home page GithubHelp logo

ustwo / formvalidator-swift Goto Github PK

View Code? Open in Web Editor NEW
495.0 17.0 33.0 1.18 MB

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

License: MIT License

Swift 93.49% Objective-C 0.57% Ruby 5.79% Shell 0.14%
macos tvos ios form-validation ustwo-library

formvalidator-swift's Introduction

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.

formvalidator-swift's People

Contributors

axellundback avatar numan1617 avatar onurersel avatar qmoya avatar sparrowlegs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

formvalidator-swift's Issues

Add Strings Files to CocoaPod

Right now CocoaPods has some issues regarding Strings files and localization. This is supposed to be fixed in Version 1.0.0. Then we can include the strings in resource_bundle tag in the podspec.

For reference to fix see:
CocoaPods/CocoaPods@3a4d1a8

Support Unicode by Default

Description

Support Unicode on Conditions and Validators by default. Exception is for email addresses, as this is still an outstanding issue (#33).

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:

  • Version Bump
  • Git Tag
  • Update Documentation
  • Podspec Update & Release

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.

Optional validator

I've created a from which conforms to Form protocol but I'd like some validations to only occur if a field is present.

I haven't figured whether this is already possible, currently I've created my own validator OptionalValidator. As an example:

public init(condition: Condition = PresentCondition(), conditions: [Condition]) {
    self.condition = condition
    self.conditions = conditions
}

// MARK: - Validator

public func checkConditions(_ text: String?) -> [Condition]? {
    if condition.check(text) {
        let violations = conditions.filter { !($0.check(text)) }
        return violations
    }
    return nil
}

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.

Update Conditions and Validators to Use Configs

Description

Many of the conditions and validators are configurable. These configurations should be condensed into struct's with the appropriate default values in the initializer. Then the config can be passed into the condition or validator rather than a whole slew of arguments. This will allow for easier extension in the future and keep method names short.

Fix Podspec Description

Description

Correct the description in the podspec.

Expected Description

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

Actual Description

An organizational tool for writing custom view controllers using UIKit.

Migrate 'Run Script Phase' Scripts to External Files

Description

There are many duplicate 'Run Script Phase' scripts in the Workspace (e.g. SwiftLint). Migrate these into common, external scripts that are called from the build phase.

Notes

  • Regardless of how many lines you type into Xcode, the proj file will compress it down into a single line which makes it hard to diff and review.
  • Having it as an external script makes it easy to run independently as needed and for easier testing of the script.

Improve iOS Example Localization

Description

Add an easy way to change the iOS Example application to use other localizations. This would be useful for testing. Ideally, the example app itself should also be localized.

Detail

Currently, the easiest way to change the language used is by going into the Info.plist file of the iOS Example and adjusting the Localization native development region (CFBundleDevelopmentRegion).

Fix Code Coverage Checks

Description

Fix code coverage checks so that it collates the results from all tests.

Expected Result

All test suites are collated into a unified coverage result.

Actual Result

Only the last test suite's results (currently the UI Tests) are reported to CodeCov.

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"))

Add macOS Support

Description

We currently support iOS and tvOS. We should also support macOS.

Details

Most of the files will compile as they are now on macOS without change. The bulk of work will be in the Controls, as these are currently very UIKit centric.

We should include a macOS example as well.

Add support for the new SwiftUI framework

Description

  • Add support for the new SwiftUI framework

Other Information

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.