RxValidator Easy to Use, Read, Extensible, Flexible Validation Checker.

Overview

License Platform Swift Version Build Status codecov.io

RxValidator

Easy to Use, Read, Extensible, Flexible Validation Checker.

It can use without Rx.

Requirements

RxValidator is written in Swift 4. Compatible with iOS 8.0+

Installation

CocoaPods

RxValidator is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'RxValidator'

At a Glance

You just use like this:

//without Rx
Validate.to(TargetValue)
    .validate(condition)
        ...
    .validate(condition)
    .asObservable() or .check()
    
//with Rx
observable
    .validate(condition)
        ...
    .validate(condition)
    .subscribe(...)
    

Usage

String

RxValidatorResult.valid //multiple condition Validate.to("[email protected]") .validate(StringShouldNotBeEmpty()) .validate(StringIsNotOverflowThen(maxLength: 50)) .validate(StringShouldBeMatch("[a-z]+@[a-z]+\\.[a-z]+")) .check() // result -> RxValidatorResult.valid ">
	
Validate.to("word is not empty")
    .validate(StringShouldNotBeEmpty())
    .check()
// result -> RxValidatorResult.valid

//multiple condition
Validate.to("[email protected]")
    .validate(StringShouldNotBeEmpty())
    .validate(StringIsNotOverflowThen(maxLength: 50))
    .validate(StringShouldBeMatch("[a-z]+@[a-z]+\\.[a-z]+"))
    .check()
// result -> RxValidatorResult.valid

Date

let targetDate: Date //2018-05-05
let sameTargetDate: Date
let afterTargetDate: Date
let beforeTargetDate: Date

Validate.to(Date())
	.validate(.shouldEqualTo(date: sameTargetDate))             //(1)
	.validate(.shouldAfterOrSameThen(date: sameTargetDate))     //(2)
	.validate(.shouldBeforeOrSameThen(date: sameTargetDate))    //(3)
	.validate(.shouldBeforeOrSameThen(date: afterTargetDate))   //(4)
	.validate(.shouldBeforeThen(date: afterTargetDate))         //(5)
	.validate(.shouldAfterOrSameThen(date: beforeTargetDate))   //(6)
	.validate(.shouldAfterThen(date: beforeTargetDate))         //(7)
	.check()
	
	// check() result
	
	// valid result  -> RxValidatorResult.valid
	
	// (1) not valid -> RxValidatorResult.notEqualDate
	// (2) not valid -> RxValidatorResult.notAfterDate
	// (3) not valid -> RxValidatorResult.notBeforeDate
	// (4) not valid -> RxValidatorResult.notBeforeDate
	// (5) not valid -> RxValidatorResult.notBeforeDate
	// (6) not valid -> RxValidatorResult.notAfterDate
	// (7) not valid -> RxValidatorResult.notAfterDate

Int

Validate.to(2)
    .validate(NumberShouldBeEven())
    .check()
    //.valid
    
Validate.to(1)
    .validate(NumberShouldBeEven())
    .check()
    //.notEvenNumber

Working with RxSwift

String

RxValidatorResult.stringIsEmpty // (2) validError -> RxValidatorResult.stringIsOverflow // (3) validError -> RxValidatorResult.stringIsNotMatch }) .disposed(by: disposeBag) ">
	
Validate.to("word is not empty")
    .validate(StringShouldNotBeEmpty())
    .asObservable()
    .subscribe(onNext: { value in
        print(value)
	//print("word is not empty")
    })
    .disposed(by: disposeBag)

Validate.to("word is not empty")
    .validate(StringShouldNotBeEmpty())
    .asObservable()
    .map { $0 + "!!" }
    .bind(to: anotherObservableBinder)
    .disposed(by: disposeBag)
	

//Multiple condition
Validate.to("[email protected]")
    .validate(StringShouldNotBeEmpty())                         //(1)
    .validate(StringIsNotOverflowThen(maxLength: 50))           //(2)
    .validate(StringShouldBeMatch("[a-z]+@[a-z]+\\.[a-z]+"))    //(3)
    .asObservable()
    .subscribe(onNext: { value in
        print(value)
        //print("[email protected]")
    },
    onError: { error in
        let validError = RxValidatorResult.determine(error: error)
        // (1) validError -> RxValidatorResult.stringIsEmpty
        // (2) validError -> RxValidatorResult.stringIsOverflow
        // (3) validError -> RxValidatorResult.stringIsNotMatch
    })
    .disposed(by: disposeBag)
		

Int

Validate.to(2)
    .validate(NumberShouldBeEven())
    .asObservable()
    .subscribe(onNext: { value in
        print(value)
        //print(2)
    })
    .disposed(by: disposeBag)
    
Validate.to(1)
    .validate(NumberShouldBeEven())
    .asObservable()
    .subscribe(onNext: { value in
        print(value)
        //print(1)
    },
    onError: { error in
        let validError = RxValidatorResult.determine(error: error)
        //validError -> RxValidatorResult.notEvenNumber
    })
    .disposed(by: disposeBag)

Date

RxValidatorResult.notEqualDate // (2) validError -> RxValidatorResult.notAfterDate // (3) validError -> RxValidatorResult.notBeforeDate // (4) validError -> RxValidatorResult.notBeforeDate // (5) validError -> RxValidatorResult.notBeforeDate // (6) validError -> RxValidatorResult.notAfterDate // (7) validError -> RxValidatorResult.notAfterDate }) .disposed(by: disposeBag) ">
let targetDate: Date //2018-05-05
let sameTargetDate: Date
let afterTargetDate: Date
let beforeTargetDate: Date

Validate.to(Date())
	.validate(.shouldEqualTo(date: sameTargetDate))             //(1)
	.validate(.shouldAfterOrSameThen(date: sameTargetDate))     //(2)
	.validate(.shouldBeforeOrSameThen(date: sameTargetDate))    //(3)
	.validate(.shouldBeforeOrSameThen(date: afterTargetDate))   //(4)
	.validate(.shouldBeforeThen(date: afterTargetDate))         //(5)
	.validate(.shouldAfterOrSameThen(date: beforeTargetDate))   //(6)
	.validate(.shouldAfterThen(date: beforeTargetDate))         //(7)
	.asObservable()
	.subscribe(onNext: { value in
        print(value) //print("2018-05-05")
	}, onError: { error in
		let validError = RxValidatorResult.determine(error: error)
		
        // (1) validError -> RxValidatorResult.notEqualDate
        // (2) validError -> RxValidatorResult.notAfterDate
        // (3) validError -> RxValidatorResult.notBeforeDate
        // (4) validError -> RxValidatorResult.notBeforeDate
        // (5) validError -> RxValidatorResult.notBeforeDate
        // (6) validError -> RxValidatorResult.notAfterDate
        // (7) validError -> RxValidatorResult.notAfterDate
	})
	.disposed(by: disposeBag)

Chaining from Observable

textField.rx.text
    .filterNil()
    .validate(StringIsAlwaysPass())
    .subscribe(onNext: { (text) in
        print(text)
    })
    .disposed(by: disposeBag)
        
let text = PublishSubject<String>()
text
    .validate(StringIsAlwaysPass())
    .subscribe(onNext: { (text) in
        print(text)
    })
    .disposed(by: disposeBag)

Instant Condition Validation

10 }) .check() Validate.to(Date()) .validate({ !$0.isToday }) .check() Validate.to("swift") .validate({ $0 == "objc" }, message: "This is not swift") .check() Validate.to(7) .validate({ $0 > 10 }, message: "Number is too small.") .check() Validate.to(Date()) .validate({ !$0.isToday }, message: "It is today!!") .check() ">
Validate.to("swift")
    .validate({ $0 == "objc" })
    .check()

Validate.to(7)
    .validate({ $0 > 10 })
    .check()

Validate.to(Date())
    .validate({ !$0.isToday })
    .check()
    

Validate.to("swift")
    .validate({ $0 == "objc" }, message: "This is not swift")
    .check()

Validate.to(7)
    .validate({ $0 > 10 }, message: "Number is too small.")
    .check()

Validate.to(Date())
    .validate({ !$0.isToday }, message: "It is today!!")
    .check()

ResultType

enum RxValidatorResult

    case notValid
    case notValidWithMessage(message: String)
    case notValidWithCode(code: Int)
    
    case undefinedError
    
    case stringIsOverflow
    case stringIsEmpty
    case stringIsNotMatch
    
    case notEvenNumber
    
    case invalidateDateTerm
    case notBeforeDate
    case notAfterDate
    case notEqualDate

Working with ReactorKit (http://reactorkit.io)

func mutate(action: Action) -> Observable {
....

case let .changeTitle(title):
  return Validate.to(title)
    .validate(StringIsNotOverflowThen(maxLength: TITLE_MAX_LENGTH))
    .asObservable()
    .flatMap { Observable<Mutation>.just(.updateTitle(title: $0)) }
    .catchError({ (error) -> Observable<Mutation> in
        let validError = ValidationTargetErrorType.determine(error: error)
        return Observable<Mutation>.just(.setTitleValidateError(validError, title))
    })

....

Supported Validation Rules

//String
StringShouldNotBeEmpty()
StringIsNotOverflowThen(maxLength: Int)
StringShouldBeMatch("regex string")

//Int
NumberShouldBeEven()

//Date
DateValidatorType.shouldEqualTo(Date)
DateValidatorType.shouldBeforeThen(Date)
DateValidatorType.shouldBeforeOrSameThen(Date)
DateValidatorType.shouldAfterThen(Date)
DateValidatorType.shouldAfterOrSameThen(Date)
DateValidatorType.shouldBeCloseDates(date: Date, termOfDays: Int)

Make custom ValidationRule like this:

//String Type
class MyCustomStringValidationRule: StringValidatorType {
    func validate(_ value: String) throws {
        if {notValidCondition} {
            throw RxValidatorResult.notValidate(code: 999) //'code' must be defined your self.  
        }
    }
}


//Int Type
class MyCustomIntValidationRule: IntValidatorType {
    func validate(_ value: Int) throws {
        if {notValidCondition} {
            throw RxValidatorResult.notValidate(code: 999) //'code' must be defined your self.  
        }
    }
}

I want to be...

  • More Built-in Validation Rules. (Help me. Welcome to PR.)
  • Support More Type (Array, Float, Double, etc)
  • More Flexible Code via Generics.
You might also like...
Comment-Spell-Checker - Xcode extension for spell checking and auto-correcting code comments.
Comment-Spell-Checker - Xcode extension for spell checking and auto-correcting code comments.

Comment Spell Checker An Xcode Source Editor extension that runs spell check and auto correct on your code comments. Features Supports mutliple commen

Cryptocurrency price checker, build with UIKit and MVC + Delegate pattern.
Cryptocurrency price checker, build with UIKit and MVC + Delegate pattern.

Coin Check Cryptocurrency price checker. The app fetch from CoinAPI.io the latest coin prices, build with UIKit and MVC + Delegate pattern. Features S

SwiftDependencyChecker - Swift Dependency Checker

SwiftDependencyChecker SwiftDependencyChecker can be installed with homebrew wit

SwiftPublicSuffixList - Public Suffix List domain name checker in Swift

SwiftPublicSuffixList This library is a Swift implementation of the necessary co

(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey 🍯 to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey 🍯 to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

CZWeatherKit is a simple, extensible weather library for iOS, tvOS, and OS X that allows for easy fetching of weather data from various weather services.
CZWeatherKit is a simple, extensible weather library for iOS, tvOS, and OS X that allows for easy fetching of weather data from various weather services.

CZWeatherKit is a simple, extensible weather library for iOS, tvOS, and OS X that allows for easy fetching of weather data from various weather services.

✂ Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit.

ManualLayout Table of Contents Installation Usage API Cheat Sheet Installation Carthage Add the following line to your Cartfile. github "isair/ManualL

SwiftRegressor - A linear regression tool that’s flexible and easy to use

SwiftRegressor - A linear regression tool that’s flexible and easy to use

A high-performance, flexible, and easy-to-use Video compressor library written by Swift.

FYVideoCompressor A high-performance, flexible and easy to use Video compressor library written by Swift. Using hardware-accelerator APIs in AVFoundat

Ruby Gem for Rails - Easy iTunes In-App Purchase Receipt validation, including auto-renewable subscriptions
Ruby Gem for Rails - Easy iTunes In-App Purchase Receipt validation, including auto-renewable subscriptions

Monza is a ruby gem that makes In-App Purchase receipt and Auto-Renewable subscription validation easy. You should always validate receipts on the ser

Write amazing, strong-typed and easy-to-read NSPredicate.

PredicateFlow Write amazing, strong-typed and easy-to-read NSPredicate. This library allows you to write flowable NSPredicate, without guessing attrib

Write amazing, strong-typed and easy-to-read NSPredicate.

PredicateFlow Write amazing, strong-typed and easy-to-read NSPredicate. This library allows you to write flowable NSPredicate, without guessing attrib

Easy to read and write chainable animations in Objective-C and Swift
Easy to read and write chainable animations in Objective-C and Swift

Whats new in version 3.x? Swiftier syntax Swift 4 support Bug fixes and improvements Whats new in version 2.x? Re-architected from the ground up, no m

⛓ Easy to Read and Write Multi-chain Animations Lib in Objective-C and Swift.
⛓ Easy to Read and Write Multi-chain Animations Lib in Objective-C and Swift.

中文介绍 This project is inspired by JHChainableAnimations! Why Choose LSAnimator & CoreAnimator? You can write complex and easy-to-maintain animations in

Fully customizable and extensible action sheet controller written in Swift
Fully customizable and extensible action sheet controller written in Swift

XLActionController By XMARTLABS. XLActionController is an extensible library to quickly create any custom action sheet controller. Examples The action

An extensible monitoring framework written in Swift

XestiMonitors Overview Reference Documentation Requirements Installation CocoaPods Carthage Swift Package Manager Usage Core Location Monitors Core Mo

A Powerful , Extensible CSS Parser written in pure Swift.
A Powerful , Extensible CSS Parser written in pure Swift.

A Powerful , Extensible CSS Parser written in pure Swift. Basic Usage From CSS: #View { "width" : 118; "height" : 120.5; "color1" : "#888888"; "co

CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant
CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant

CleanroomLogger CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant. The API provided by Cleanro

Comments
  • Fix DateValidatorType

    Fix DateValidatorType

    Given func testDateValidation() does not cover after target date because it's same to target date

    let targetDate = "2018-05-29T12:00+09:00".date(format: .iso8601Auto)!.absoluteDate
    let afterTargetDate = "2018-05-29T12:00+09:00".date(format: .iso8601Auto)!.absoluteDate
    
    • Add unit test for after target date and fix failed test case
    • Add unit test for same target date when validate with .shouldBeforeThen or .shouldAfterThen fix failed test case

    related links https://developer.apple.com/documentation/foundation/comparisonresult

    Constants case orderedAscending The left operand is smaller than the right operand.

    case orderedSame The two operands are equal.

    case orderedDescending The left operand is greater than the right operand.

    opened by cruisediary 2
  • Usability improvements and support some features.

    Usability improvements and support some features.

    Simplify usage.

    Improve code for extensibility using Extension.

    /// Before
    Validate.to("Test")
      .validate(StringShouldNotBeEmpty())
      ...
    
    /// After
    Validate.to("Test")
      .validate(.shouldNotBeEmpty)
      ...
    

    Added method that validating with the custom message.

    For the below situations:

    Observable
      .combineLatest(
        state.map { $0.email }
          .validate(.shouldNotBeEmpty, message: "Empty email.")
          .validate(.isNotOverflowThen(max: 50), message: "Overflow email.")
          .validate(.shouldBeMatch("[a-z]+@[a-z]+\\.[a-z]+"), message: "Not email address."),
        state.map { $0.password }
           .validate(.shouldNotBeEmpty, message: "Empty password.")
           .validate(.isNotUnderflowThen(min: 6), message: "Password too short.")
      ) { Credential(email: $0, password: $1) }
      ...
    

    I suggest the following method:

    Validate.to("Test")
        .validate(.shouldEqualTo("Not Equal", message: "Custom Message"))
        .check()
    
    /// Throws `RxValidatorResult.notValidWithMessage(message: "Custom Message")`
    

    Support Numeric type.

    Added some validate rules for Numeric types using generics.

    • NumberShouldEqualTo()
    • NumberShouldGreaterThan()
    • NumberShouldLessThan()

    and, IntValidator has integrated into NumberValidator.

    Delete Example.

    This example is only for testing, so added test in the base project and remove it.

    Others

    • Changed the architecture between Validator to be the same.
    • Add some rules.
    • Increase test coverage.
    opened by kawoou 1
Owner
GeumSang Yoo
GeumSang Yoo
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
String (and more) validation for iOS

Swift Validators ?? String validation for iOS. Contents Installation Walkthrough Usage Available validators License ReactiveSwift + SwiftValidators Wa

George Kaimakas 241 Nov 13, 2022
Drop in user input validation for your iOS apps.

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

Adam Waite 1.4k Dec 29, 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
Validation plugin for Moya.Result

MoyaResultValidate Why? Sometimes we need to verify that the data returned by the server is reasonable, when Moya returns Result.success. JSON returne

Insect_QY 1 Dec 15, 2021
Input Validation Done Right. A Swift DSL for Validating User Input using Allow/Deny Rules

Valid Input Validation Done Right. Have you ever struggled with a website with strange password requirements. Especially those crazy weird ones where

Mathias Quintero 37 Nov 3, 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
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
Updeto is a simple package that help update checker for iOS Apps

Updeto is a simple package that will help you to check if the currently installed version is the same as the latest one available on App Store.

Manuel Sánchez 8 Jul 8, 2022
Objective-C style checker

ocstyle Objective-C style checker Installation pip install ocstyle Example If you have a file called test.m like this: @implementation SomeClass +(v

Cue 256 Feb 2, 2022