Git Product home page Git Product logo

validator's Introduction

Validator

Validator is a user input validation library written in Swift. It's comprehensive, designed for extension, and leaves the UI up to you.

Here's how you might validate an email address:

let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)
"invalid@email,com".validate(emailRule) // -> .invalid(validationError)

... or that a user is over the age of 18:

let eighteenYearsAgo = Date().addingTimeInterval(-568024668)
let drinkingAgeRule = ValidationRuleComparison<Date>(min: eighteenYearsAgo, error: validationError)
let dateOfBirth = Date().addingTimeInterval(-662695446) // 21 years old
dateOfBirth.validate(rule: rule) // -> .valid

... or that a number is within a specified range:

let numericRule = ValidationRuleComparison<Int>(min: 50, max: 100, error: validationError)
42.validate(numericRule) // -> .invalid(validationError)

.. or that a text field contains a valid Visa or American Express card number:

let cardRule = ValidationRulePaymentCard(availableTypes: [.visa, .amex], error: validationError)
paymentCardTextField.validate(cardRule) // -> .valid or .invalid(validationError) depending on what's in paymentCardTextField

Features

  • Validation rules:
    • Required
    • Equality
    • Comparison
    • Length (min, max, range)
    • Pattern (email, password constraints and more...)
    • Contains
    • URL
    • Payment card (Luhn validated, accepted types)
    • Condition (quickly write your own)
  • Swift standard library type extensions with one API (not just strings!)
  • UIKit element extensions
  • Open validation error types
  • An open protocol-oriented implementation
  • Comprehensive test coverage
  • Comprehensive code documentation

Demo

demo-vid

Installation

CocoaPods

CocoaPods Compatible CocoaPods Compatible

pod 'Validator'

Carthage

Carthage Compatible

github "adamwaite/Validator"

Usage

Validator can validate any Validatable type using one or multiple ValidationRules. A validation operation returns a ValidationResult which matches either .valid or .invalid([Error]).

let rule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)

let result = "invalid@email,com".validate(rule: rule)
// Note: the above is equivalent to Validator.validate(input: "invalid@email,com", rule: rule)

switch result {
case .valid: print("๐Ÿ˜€")
case .invalid(let failures): print(failures.first?.message)
}

Validation Rules

Required

Validates a type exists (not-nil).

let stringRequiredRule = ValidationRuleRequired<String?>(error: validationError)

let floatRequiredRule = ValidationRuleRequired<Float?>(error: validationError)

Note - You can't use validate on an optional Validatable type (e.g. myString?.validate(aRule...) because the optional chaining mechanism will bypass the call. "thing".validate(rule: aRule...) is fine. To validate an optional for required in this way use: Validator.validate(input: anOptional, rule: aRule).

Equality

Validates an Equatable type is equal to another.

let staticEqualityRule = ValidationRuleEquality<String>(target: "hello", error: validationError)

let dynamicEqualityRule = ValidationRuleEquality<String>(dynamicTarget: { return textField.text ?? "" }, error: validationError)

Comparison

Validates a Comparable type against a maximum and minimum.

let comparisonRule = ValidationRuleComparison<Float>(min: 5, max: 7, error: validationError)

Length

Validates a String length satisfies a minimum, maximum or range.

let minLengthRule = ValidationRuleLength(min: 5, error: validationError)

let maxLengthRule = ValidationRuleLength(max: 5, error: validationError)

let rangeLengthRule = ValidationRuleLength(min: 5, max: 10, error: validationError)

Pattern

Validates a String against a pattern.

ValidationRulePattern can be initialised with a String pattern or a type conforming to ValidationPattern. Validator provides some common patterns in the Patterns directory.

let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)

let digitRule = ValidationRulePattern(pattern: ContainsNumberValidationPattern(), error: someValidationErrorType)

let helloRule = ValidationRulePattern(pattern: ".*hello.*", error: validationError)

Contains

Validates an Equatable type is within a predefined SequenceType's elements (where the Element of the SequenceType matches the input type).

let stringContainsRule = ValidationRuleContains<String, [String]>(sequence: ["hello", "hi", "hey"], error: validationError)

let rule = ValidationRuleContains<Int, [Int]>(sequence: [1, 2, 3], error: validationError)

URL

Validates a String to see if it's a valid URL conforming to RFC 2396.

let urlRule = ValidationRuleURL(error: validationError)

Payment Card

Validates a String to see if it's a valid payment card number by firstly running it through the Luhn check algorithm, and secondly ensuring it follows the format of a number of payment card providers.

public enum PaymentCardType: Int {
    case amex, mastercard, visa, maestro, dinersClub, jcb, discover, unionPay
    ///...

To be validate against any card type (just the Luhn check):

let anyCardRule = ValidationRulePaymentCard(error: validationError)

To be validate against a set of accepted card types (e.g Visa, Mastercard and American Express in this example):

let acceptedCardsRule = ValidationRulePaymentCard(acceptedTypes: [.visa, .mastercard, .amex], error: validationError)

Condition

Validates a Validatable type with a custom condition.

let conditionRule = ValidationRuleCondition<[String]>(error: validationError) { $0.contains("Hello") }

Create Your Own

Create your own validation rules by conforming to the ValidationRule protocol:

protocol ValidationRule {
    typealias InputType
    func validate(input: InputType) -> Bool
    var error: ValidationError { get }
}

Example:

struct HappyRule {
    typealias InputType = String
    var error: ValidationError
    func validate(input: String) -> Bool {
        return input == "๐Ÿ˜€"
    }
}

If your custom rule doesn't already exist in the library and you think it might be useful for other people, then it'd be great if you added it in with a pull request.

Multiple Validation Rules (ValidationRuleSet)

Validation rules can be combined into a ValidationRuleSet containing a collection of rules that validate a type.

var passwordRules = ValidationRuleSet<String>()

let minLengthRule = ValidationRuleLength(min: 5, error: validationError)
passwordRules.add(rule: minLengthRule)

let digitRule = ValidationRulePattern(pattern: .ContainsDigit, error: validationError)
passwordRules.add(rule: digitRule)

Validatable

Any type that conforms to the Validatable protocol can be validated using the validate: method.

// Validate with a single rule:

let result = "some string".validate(rule: aRule)

// Validate with a collection of rules:

let result = 42.validate(rules: aRuleSet)

Extend Types As Validatable

Extend the Validatable protocol to make a new type validatable.

extension Thing : Validatable { }

Note: The implementation inside the protocol extension should mean that you don't need to implement anything yourself unless you need to validate multiple properties.

ValidationResult

The validate: method returns a ValidationResult enum. ValidationResult can take one of two forms:

  1. .valid: The input satisfies the validation rules.
  2. .invalid: The input fails the validation rules. An .invalid result has an associated array of types conforming to ValidationError.

Errors

Initialize rules with any ValidationError to be passed with the result on a failed validation.

Example:

struct User: Validatable {

    let email: String

    enum ValidationErrors: String, ValidationError {
        case emailInvalid = "Email address is invalid"
        var message { return self.rawValue }
    }

    func validate() -> ValidationResult {
        let rule ValidationRulePattern(pattern: .emailAddress, error: ValidationErrors.emailInvalid)
        return email.validate(rule: rule)
    }
}

Validating UIKit Elements

UIKit elements that conform to ValidatableInterfaceElement can have their input validated with the validate: method.

let textField = UITextField()
textField.text = "I'm going to be validated"

let slider = UISlider()
slider.value = 0.3

// Validate with a single rule:

let result = textField.validate(rule: aRule)

// Validate with a collection of rules:

let result = slider.validate(rules: aRuleSet)

Validate On Input Change

A ValidatableInterfaceElement can be configured to automatically validate when the input changes in 3 steps.

  1. Attach a set of default rules:

    let textField = UITextField()
    var rules = ValidationRuleSet<String>()
    rules.add(rule: someRule)
    textField.validationRules = rules
  2. Attach a closure to fire on input change:

    textField.validationHandler = { result in
      switch result {
      case .valid:
    	    print("valid!")
      case .invalid(let failureErrors):
    	    let messages = failureErrors.map { $0.message }
        print("invalid!", messages)
      }
    }
  3. Begin observation:

    textField.validateOnInputChange(enabled: true)

Note - Use .validateOnInputChange(enabled: false) to end observation.

Extend UI Elements As Validatable

Extend the ValidatableInterfaceElement protocol to make an interface element validatable.

Example:

extension UITextField: ValidatableInterfaceElement {

    typealias InputType = String

    var inputValue: String { return text ?? "" }

    func validateOnInputChange(enabled: Bool) {
        switch validationEnabled {
        case true: addTarget(self, action: #selector(validateInputChange), forControlEvents: .editingChanged)
        case false: removeTarget(self, action: #selector(validateInputChange), forControlEvents: .editingChanged)
        }
    }

    @objc private func validateInputChange(_ sender: UITextField) {
        sender.validate()
    }

}

The implementation inside the protocol extension should mean that you should only need to implement:

  1. The typealias: the type of input to be validated (e.g String for UITextField).
  2. The inputValue: the input value to be validated (e.g the text value for UITextField).
  3. The validateOnInputChange: method: to configure input-change observation.

Examples

There's an example project in this repository.

Contributing

Any contributions and suggestions are most welcome! Please ensure any new code is covered with unit tests, and that all existing tests pass. Please update the README with any new features. Thanks!

Contact

@adamwaite

License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

validator's People

Contributors

adamwaite avatar appsolute avatar dacchan avatar ellliott avatar hcemozturk avatar jedmund avatar joshluongo avatar metabren avatar mickmaccallum avatar mjjimenez avatar orta avatar oscarvgg avatar pappalar avatar rolandasrazma avatar sdduursma avatar shayna34 avatar shoaibahmedqureshi avatar shun-nakahara avatar tlb-xiongju avatar toastersocks avatar txaiwieser avatar whiskey avatar yakubbaev avatar yonaskolb 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

validator's Issues

No Documentation for any method

Hello!

I just started using this framework, which is very cool and flexible ๐Ÿ‘

I wanted to raise a point.
There is no documentation on any method/class in this project.

This is very cumbersome because it forces me (or any new user) to read the entire source code to understand why there is a specific parameter, or what are the other methods that are not documented in the README etc..

For example I had to look for validateOnEditingEnd which is exactly what I need, but I had to check the source code to be sure,
while some documentation would let me do the same thing from my editor, which is the purpose of using a framework instead of writing myself the whole code

just my 2cents

ValidationRuleLength on Nil

This rule will always trigger when String? is nil. If the string is nil and min >= 0 then this should probably treat the nil string as an empty string.

input?.characters.count >= min
false

validator dependencies

Really nice library :)

It would be great to be able to set a priority of dependencies. At the moment if setting the required and min length validator for example, it will return errors for both. It would be nice if you could set that it will only validate min length if required is already validated. This becomes especially useful with remote validation i.e. don't bother hammering the server if the instance is not at least 5 chars. Make sense or is there a way of doing similar already that I totally missed (without doing a bunch of unique validators stuck inside an if isvalid condition)?

Should validate() have @discardableResult in Swift 3.0?

I'm getting a lot of Result of call to 'validate()' is unused warnings.

This could just be how I've implemented Validator in my app, but if not, we should add @discardableResult to the validate function to silence these warnings. I'm happy to make the changes if others think this is the right way to go.

Error while trying to set via Carthage

I`m getting this error when I add this repo in my Cartfile. like this:
github "adamwaite/Validator"
this is the error:

`Failed to discover shared schemes in project Example.xcodeproj โ€” either the project does not have any shared schemes, or xcodebuild timed out.

If you believe this to be a project configuration error, please file an issue with the maintainers at https://github.com/adamwaite/Validator/issues/new`

What can I do?

Require Function

Hello All,

I have a really quick question, is there an example for using the require function? I've tried implementing and once I use

let stringRequiredRule = ValidationRuleRequired<String?>(failureError: ValidationError(message: "๐Ÿ˜ซ"))

stringCell.validationRuleSet?.add(rule: stringRequiredRule)

I get the following error
Generic parameter 'R' could not be inferred

Email regex too strict

The regex requires a TLD, which isn't required in the email address spec[0]. There's been a lot written[1] about email regex that's too strict and I tend to agree that it's better to have false positives than false negatives, especially with a default validator. The regex actually fails a lot of valid email addresses (although most will likely rarely appear).

Here's a list[2] of valid email address the regex fails,

  • "much.more unusual"@example.com
  • "[email protected]"@example.com
  • "very.(),:;<>[]".VERY."very@\ "very".unusual"@strange.example.com
  • admin@mailserver1
  • #!$%&'*+-/=?^_`{}|[email protected]
  • "()<>[]:,;@\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
  • " "@example.org (space between the quotes)
  • example@localhost (sent from localhost)
  • user@com
  • user@localserver
  • user@[IPv6:2001:db8::1]

[0] https://tools.ietf.org/html/rfc2822#section-3.4
[1] Email spec in ABNF and also includes the regex implementation https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
[2] Taken from https://en.wikipedia.org/wiki/Email_address#Valid_email_addresses

Validator Fields with Mask

Is it possible to have a Validator field with a regex mask? like "xxx-xxx-xxxx"
I want it automatically adds the extra characters. If the user inputs "1234567890" it shows "123-456-7890"

Example for Required rule is not correct

In README you have

let stringRequiredRule = ValidationRuleRequired<String?>(error: someValidationErrorType)

let floatRequiredRule = ValidationRuleRequired<Float?>(error: someValidationErrorType)

If you specify you rule type as optional, you will get double optionals inside validate method and it will always evaluate input as valid, making the rule useless. (Input to validate method is already specified as Optional of generic type, so for String? type you will then get String?? inside the method)

Correct way to validate on submit

Hello,

It appears that all validation is completed inline. Is there a way to double confirm validation on submit of a form for example.

I want to either check the current validation status or revalid against the same rule again to confirm. Otherwise when a submit button is pressed there might be multiple rows still in a bad state.

Thanks

Files missing in CocoaPods?

I just did a Pod Update and my build now gets the error:
/Users/gavin/montherly/Montherly/Pods/ALPValidator/ALPValidator/ALPValidator.h:31:9: 'UIView+ALPValidator.h' file not found

I checked the Pod file and noticed it in fact was not included (but did notice it in this repo) - was there a mistake with the cocoapod?

Swift 3 deprecations fix in release

Hi!
The currently released version still has deprecation warnings in it because of things like associatedtype and new selector syntax. I've seen that there is a commit in master that fixes it, but I would like to ask when will it be available via a release? It is not too good to point to the master branch in a production code.

Thank you!

ValidationRulePattern NSPredicate

    /**
     
     Initializes a `ValidationRulePattern` with a regular expression in string 
     format, and an error describing a failed
     validation.
     
     - Parameters:
        - pattern: A regular expression in string format to evaluate an input 
        against.
        - error: An error describing a failed validation.
     
     */
    public init(pattern: String, error: Error) {
        self.pattern = pattern
        self.error = error
    }

But internally it uses

    public func validate(input: String?) -> Bool {
        return NSPredicate(format: "SELF MATCHES %@", pattern).evaluate(with: input)
    }

which is actually not the same with NSRegularExpression. NSPredicate mathches doesn't recognizes many patterns which NSRegularExpression does.

[question] only iOS7?

Hi,
Why you set project target on iOS7?
I was really suprise when cocoapods told me :
"[!] The platform of the target Pods (iOS 6.0) is not compatible with ALPValidator (0.0.2) which has a minimum requirement of iOS 7.0."

Are you use any method iOS7 only?

How to use custom rule in swift 3.0

Hi @adamwaite ,
I am using Validator in my project.
Can you please help me in using custom rule in swift 3.0
Please check below code:

internal struct WhitespaceRule {
    typealias InputType = String
    var error: ValidationError = ValidationError(message: "")
    init(message: String?) {
        self.error = ValidationError(message: message ?? "Please enter valid character")
    }
    func validate(input: String?) -> Bool {
        guard let nameText = input else { return false }
        let trimmedString = nameText.trimmingCharacters(in: CharacterSet.whitespaces)
        return !trimmedString.isEmpty
        return true
    }
}

But when I use this rule in my class like

nameRules.add(rule: WhitespaceRule(message: "Please enter an item name"))

It is giving me error argument type 'WhitespaceRule' does not conform to expected type 'ValidationRule'

}

Init RuleSet with multiple rules

import Validator

extension String: Error {}

extension ValidationRuleSet {
    static var email: ValidationRuleSet<String> {
        return ValidationRuleSet<String>(rules: [
            ValidationRuleLength(min: 1, max: Int.max, error: R.string.localizable.authEmptyEmail()),
            ValidationRulePattern(pattern: EmailValidationPattern.standard,
                                  error:R.string.localizable.authInvalidEmail())
            ])
    }
}

I'm trying to create a rule set for UITextField, but it says that Cannot convert value of type '[Any]' to expected argument type '[_]'. What's wrong?

Potentially risky use of copy-properties

In AJWValidator there are two properties of type NSMutableArray, which are declared as copy. If one would use these properties to set the respective arrays it would cause a problem which most likely will result in a crash:

self.mutableErrorMessages = [NSMutableArray array];

[self.rules addObject:@"test"]; 
/*Preceding line results in: Terminating app due to uncaught exception 'NSInvalidArgumentException',  reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance*/

Due to the usage of copy, the setter would copy the given NSMutableArray into an IMMUTABLE NSArray instance hence causing every call of NSMutableArray specific methods to throw an NSInvalidArgumentException.

Retain Cycles

First of all: Great job on this project! I love using it!

I was wondering if it is intentional that validationRuleSets and validationHandler are strongly referenced and that they cannot be set to nil. I'm trying to get my code as efficient as possible and this prevents ViewController from being deinitialized.

Thanks in advance

Problem with CocoaPod Update

I was updating CocoaPods for one of my projects and ran into the following error:

Update all pods
Analyzing dependencies
Downloading dependencies
Installing ALPValidator (0.0.3)
[!] Pod::Executable remote update

error: cannot open FETCH_HEAD: Permission denied

I am pretty much a CocoaPod newbie, so I have no clue what this error means or whether it is something I can fix. Can you help me?

Empty Validation Rule

I guess such a validation rule is pretty common.
Although this could be as simple as ValidationRuleLength(min: 1, failureError: error) having a shortcut method for it would be awesome.
Useful and fast enhancement

How to make UITextView implement ValidatableInterfaceElement?

Hello,

Great library! I have really enjoyed using it so far to validate UITextField's, it was painless. I was wondering how one could validate for a UITextView. After reading the readme, I came up with:

extension UITextView: ValidatableInterfaceElement {

    public typealias InputType = String

    var inputValue: String { return text ?? "" }

    public func validateOnInputChange(validationEnabled: Bool) {
        switch validationEnabled {
        case true: addTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
        case false: removeTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
        }
    }

    @objc private func validateInputChange(sender: UITextView) {
        sender.validate()
    }

}

which is probably very wrong, because it is just a copy and paste, and the compiler gives these errors:

Type 'UITextView' does not conform to protocol 'ValidatableInterfaceElement'
Use of unresolved identifier addTarget
Use of unresolved identifier removeTarget

These errors make sense, because UITextView does not have addTarget/removeTarget methods. Sadly, my Swift-fu and Obj-C-fu are laughable, but it seems possible as in the following Stackoverflow question:

http://stackoverflow.com/questions/17497891/how-to-make-a-uitextview-call-the-addtarget-method

I tried making my UIViewController that has the UITextView implement UITextViewDelegate, and then:

    func textViewDidChange(textView: UITextView) {
        keyText = textView.text
    }

but I am not sure how to wire this all up and make it work. Any ideas/suggestions? Also this could be an opportunity to add to the library, like UITextView+Validator.swift, as it would seem to be a pretty common thing, at least I would think so :).

Thanks very much.

FatalError when no attached rules

Is this a really good behaviour?

I have an array of text fields for UIViewController and I iterate over all and run validate() and merging the result of the validation... But if there is no attached rules fatal error is thrown...

Personally, I would suggest returning .valid if there is no rules attached to ValidatableInterfaceElement instead of throwing fatal error. What do you think guys?

Revise ValidationPattern enum to handle Associated Values

Hi Adam,

My team and I recently added a postcode validation pattern to Validator and have encountered the following issue when a validation pattern has a number of options. For example, UK postcodes can be provided lowercase, uppercase, with a space or without a space. Currently, we could provide a separate enum case for each according to the validation required, however, this quickly becomes unwieldy.

An alternative is to restructure the ValidationPattern enum to handle associated values and return the appropriate regex as follows:

enum PostcodeOptions {
    case AllowsOptionalSpace
}

enum ValidationPattern {
    case EmailAddress
    case ContainsNumber
    case ContainsCapital
    case ContainsLowercase
    case UKPostcode(options: [PostcodeOptions])

    var pattern: String {
        switch self {
        case .EmailAddress:
            return "^[_A-Za-z0-9-+]+(\\.[_A-Za-z0-9-+]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-zโ€Œโ€‹]{2,})$"
        case .ContainsNumber:
            return ".*\\d.*"
        case .ContainsCapital:
            return "^.*?[A-Z].*?$"
        case .ContainsLowercase:
            return "^.*?[a-z].*?$"
        case .UKPostcode(let options):
            let optionalSpace = options.contains(.AllowsOptionalSpace) ? "[ ]?" : " "
            return "(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY]))))\(optionalSpace)[0-9][A-Z-[CIKMOV]]{2})"
        }
    }
}

You could also group the string patterns .ContainsNumber, .ContainsCapital, .ContainsLowercase into their own options group and construct the regex in a .String case creating one validation rule from multiple options.

I understand this proposal would change how users currently create validations and so wanted to first sound out your view on the value of this.

Many thanks

Carthage Support

Hi there,

may anyone have knowledge to add Carthage support for this great library ?

It would be great since Carthage become popular nowadays.

Thanks.

Validate on input change blows up for UITextField subclasses

Validate on input change blows up for UITextField subclasses on this line with the following message:

Could not cast value of type 'Validator.(Box in _8483EA982F7B609A32A9F5BE7106930E)<(Validator.ValidationResult, MyApp.MyTextField) -> ()>' (0x1257e01b0) to 'Validator.(Box in _8483EA982F7B609A32A9F5BE7106930E)<(Validator.ValidationResult, UITextField) -> ()>' (0x1257e0330).

I came up with a workaround by overriding methods and properties declared by ValidatableInterfaceElement in my MyTextField, but it would be nice if I didn't need to do that :)

extension MyTextField {

    typealias InputType = String

    override var inputValue: String { return text ?? "" }

    override func validateOnInputChange(validationEnabled: Bool) {
        switch validationEnabled {
        case true: addTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
        case false: removeTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
        }
    }

    @objc private func validateInputChange(sender: MyTextField) {
        sender.validate()
    }

}

Any ideas on how to approach this issue?

Mobile regex

Could you add good regex pattern for international mobile as well as UIextField, which automatically format phone humber (like PhoneNumberKit)?

Swift 3.0 Support

Hello,

I've been working on a Swift 3.0 update but have run into a gnarly crash I don't know how to fix. If anyone else wants to pick it up from here and fix it, or point me in the right direction, I'd greatly appreciate it!

I think I've tracked down the issue to objc_getAssociatedObject receiving an object that can't be turned into a ValidationRuleSet, but I'm not 100% sure on that. I am pretty sure that the bug is something in ValidatableInterfaceElement.swift though.

Minimum deployment target iOS 9

I added the module via Carthage. But I get this error:

Module file's minimum deployment target is ios9.0 v9.0: /Users/*/Carthage/Build/iOS/Validator.framework/Modules/Validator.swiftmodule/x86_64.swiftmodule

Isn't it possible to target on iOS 8?

ValidationErrorType Priority

What is the best way to handle Error priority so that when multiple rules are hit, we can easily identify the priority of the rules? The point of validation does not know priority of the validation in a ValidationRuleSet.

check if specific field failed validation

Is there any way to check if a specific field has failed the validation?
I have a UIView under each textfield, and I want to color the UIView red under the textfield that fails validation.

And big thanks for sharing this lib!

Numbers only

Is there a way to make a validation rule for numbers only? I see contains digits, but looking to have a textfield that can only accept numbers.

Thanks

Crashing when validationRules = nil

Hi @adamwaite,
public func validate() -> ValidationResult {
guard let attachedRules = validationRules else { fatalError("Validator Error: attempted to validate without attaching rules") }
return validate(rules: attachedRules)
}
as ValidationResult is return type and its not optional so when validationRules is coming nil then guard statement doesn't working properly because not returning anything.
Could anyone look into this.

Why differentiate between ValidationRule and ValidationRuleSet?

This is an awesome project. A real treasure trove of Swift patterns for us newbies. I feel odd filing an issue for a general question. Maybe it would be a good idea to start up a Google Group, or something of that ilk?

Why differentiate between ValidationRule and ValidationRuleSet? I would have thought that ValidationRuleSet would inherit from ValidationRule. I'm sure that I'm missing some overriding pattern. TIA

ValidationDateRangeRule

Greetings again, one final question, I noticed that in the pull requests there use to exist a Date Range validation rule. Was this ever merged into the main library?

Sent Events section disappeared from Connections Inspector/Menu

When I add Validator to my project, the "Sent Events" section disappears from my Storyboard's Connections Inspector/Menu. I'm a bit of a GUI weenie so I was alarmed at first. I know that I can hand code Target/Action connections, so I calmed down after a while. But still, I'd still like to mix both Validator and Storyboard managed Target/Action connections.

Is that possible?

Why did the the "Sent Events" section disappear? I sense an opportunity to learn about the deeper workings of Storyboard, hand registration of target/actions for particular events.

ValidationRuleSet.init(rules: [AnyValidationRule])

With the use of Self in the ValidationRuleSet struct, we cannot mix rules in the current inits when one rule has an associated type and others do not. Should there be an init method so we can pass in the type erasure form of the rule and open up the possibly of passing [AnyValidationRule] instead of having to .add() for each and every rule?

ValidationRuleSet not working with Required rule

when i have a validationrulest and add a required rule and others (e.g. email), then only email is validated, the required rule is ignored.

i think it is because string cannot be nil... why dont you check for empty string if type is string in the required rule?

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.